Tuesday, March 5, 2013

A Better way to attach custom SP2010 event receivers

I recently decided to take a deeper look into code which is used to programmatically attach or remove a SharePoint event receiver against a SharePoint list.

Using the SharePoint 2010 Object Model to programmatically add or remove an event receiver is really simple….and that is exactly the problem I came across. As developers we sometimes tend to have a ‘get the job done’ attitude and we do exactly that…we write code which executes without any problems and which delivers the expected results, so we consider the job done and we move on. If we want to build robust code we have to consider the different syntax options and implement what we believe is most relevant in the particular scenario.

So I took the C# code and made slight changes to it and now I get much better (and more granular) control. I am now able to programmatically set the SharePoint custom event receiver properties.

Scenario: I have a SharePoint 2010 site which contains a number of custom event receivers. These event receivers can be web scoped, site scoped, or list scoped (this example). Based on a specific action (trigger) I want to programmatically attach or remove the custom event receivers to / from their target. Examples of triggers are: a business rule (workflow), a custom page code behind (like a settings page), provisioning logic, etc. So, the code which manages the event receivers can live almost anywhere. In this example I make use of a custom provisioning feature to manage the event receivers. In other words if my custom provisioning feature is activated it will attach my custom event receivers and when the feature is deactivated it will remove the event receivers.

This is the old code before I made changes:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    using (SPWeb web = properties.Feature.Parent as SPWeb)
    {
        SPList list = web.Lists.TryGetList("test");
        if (list != null)
        {
            string classname = "SharePointDemoCode.Custom.EventReceivers.SetDealValuesReceiver";
            string assembly = "SharePointDemoCode, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1ee7eff4c43a8776";
            web.AllowUnsafeUpdates = true;
            list.EventReceivers.Add(SPEventReceiverType.ItemAdded, assembly, classname);
            web.AllowUnsafeUpdates = false;
        }
    }
}

This code will attach the event receiver without any problems but if I use SharePointEventReceiverManager.exe to analyse the event receiver association I can see that the event sequence number set to 10000 (default value) and the event receiver name is empty.

image

So to have control over the above mentioned properties one can rather use the following code:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    using (SPWeb web = properties.Feature.Parent as SPWeb)
    {
        SPList list = web.Lists.TryGetList("test");
        if (list != null)
        {
            string classname = "SharePointDemoCode.Custom.EventReceivers.SetDealValuesReceiver";
            string assembly = "SharePointDemoCode, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1ee7eff4c43a8776";

            SPEventReceiverDefinitionCollection eventReceivers = list.EventReceivers;
            SPEventReceiverDefinition neweventReceiver = eventReceivers.Add();
            neweventReceiver.Name = "Set Deal Values Receiver";
            neweventReceiver.Synchronization = SPEventReceiverSynchronization.Default;
            neweventReceiver.Type = SPEventReceiverType.ItemAdded;
            neweventReceiver.SequenceNumber = 25001;
            neweventReceiver.Assembly = assembly;
            neweventReceiver.Class = classname;
            neweventReceiver.Update();
        }
    }
}

From the image below you can see that the event sequence number set to 25001  and the event receiver name is ‘Set Deal Values Receiver’ – this is exactly what I wanted to have control over.

image

To remove / detach an event receiver use the following code:

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
    string classname = "SharePointDemoCode.Custom.EventReceivers.SetDealValuesReceiver";

    using (SPWeb web = properties.Feature.Parent as SPWeb)
    {
        SPList list = web.Lists.TryGetList("test");
        if (list != null)
        {
            IEnumerable<SPEventReceiverDefinition> eventReceiverResults = list.EventReceivers.Cast<SPEventReceiverDefinition>().Where(receiver => string.Equals(receiver.Class, classname, StringComparison.OrdinalIgnoreCase));

            if (eventReceiverResults.Any())
            {
                foreach (SPEventReceiverDefinition eventReceiver in eventReceiverResults.ToList())
                {
                    list.EventReceivers[eventReceiver.Id].Delete();
                }
            }
        }
    }
}

For a complete list of SPEventReceiverDefinition Members go to: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.speventreceiverdefinition_members(v=office.14).aspx

4 comments:

ADmin said...

And essayists think in light of the fact that they headed off to class, adore dialect, know their this site punctuation and swing around a stellar vocabulary, that they have the answer.

Vanessa said...

This is cool!

Unknown said...

Hi,HTML allows creation of Web pages that can be viewed using a Web browser for Web Design Cochin. HTML allows the precise placement of text and images and enables navigation through the use of hyperlinks. Thanks.....

Anonymous said...

Good Article

Post a Comment