Saturday, April 19, 2014

SharePoint 2013 - Creating an Event Receiver

In the previous post, we had an overview of Event Receivers. In this post we will create an Item Added event receiver to understand the basic functionality in a little more detail.

Objective
We need to accomplish the following tasks for this demo:
1) Create a custom list named 'Customers' with just name and address.
2) Create a custom list named 'Orders' and add Customer's 'Title' as a lookup field.
3) Add an event handler to retrieve the Customer's 'Address' and save it as 'Shipping address' in the Orders list in the ItemAdded event.

Steps for creating the event receiver
Following are the steps for creating the Event Receiver.

1) Create a custom list named "Customers" with the fields as shown in the following figure.

2) Enter some sample data in the "Customers" list.

3) Create another custom list named "Orders" with the fields as shown in the following figure. Make sure "Title" field from "Customers" List is added as lookup field in this list.


4) Create sample data for Orders list and leave the "ShippingAddress" filed blank.

5) Right now "ShippingAddress" field remains blank.

We need to target that whenever a new item is created, the "ShippingAddress" field should be updated with the value from "Address" field in the "Customers" List.

6) Open Visual Studio 2010 and create a new project named "EventReceiverDemo". Add a new feature named "OrderProcess" scoped as web.

7) Right click on the solution and add a new EventReceiver named "OrdersEventReceiver" as follows.

8) You will be prompted with a dialogue for choosing the List Type (eg: Custom list, Announcement etc) and the event that will bind with this list. Choose "An item was added".

9) A new class is created named OrdersEventReceiver inherited from SPItemEventReceiver base class which contains the ItemAdded Event.

10) Added the following code in the ItemAdded Event. Its just a simple code for getting the Customer Name (ID;#Title format) from the current item being saved. Using the 'Id' we get the details from the "Customers" List and update in the "ShippingAddress" filed of the current.
Code Snippet
public override void ItemAdded(SPItemEventProperties properties)
        {
            base.ItemAdded(properties);
            //Elevate the permissions to Admin level for performing this operation.
            SPSecurity.RunWithElevatedPrivileges(delegate
            {
                //Get the selected Customer's Look up Title (Eg: "1;#NealMukundan")
                SPListItem CurrentItem = properties.ListItem;
                String strCustomer = CurrentItem["Customer"].ToString();

                //Get the selected Customer's ID using Substring
                int startPos = 0;
                int endPos = CurrentItem["Customer"].ToString().IndexOf(";#");
                int Cust_ID = Convert.ToInt32(strCustomer.Substring(startPos, endPos));

                //Get the list items from 'Customers' List using Customer ID.
                SPWeb oWeb = properties.Web;
                SPList oList = oWeb.Lists["Customers"];
                SPListItem Customers = oList.GetItemById(Cust_ID);

                //Assign the 'Address' from Customers List to the 'Shipping Address' in the Current Item.
                CurrentItem["ShippingAddress"] = Customers["Address"];
                CurrentItem.Update();

                //Update the current item
                oWeb.AllowUnsafeUpdates = true;
                oWeb.Update();
                oWeb.AllowUnsafeUpdates = false;
            });
        }

11) Now that we have created the Event Receiver, we must bind it to the 'Orders' List using a Feature Receiver.

12) Right click on the Feature and an new Feature Receiver as follows.

13) Open the 'Elements.xml' linked to the 'OrdersEventReceiver.cs' file since we will use this data to override the Feature Receiver Events.

14) Added the following code in the FeatureActivated event. We need to create an event receiver definition using the SPEventReceiverDefinition class. You can get the values for definition from the XML file mentioned in the previous step.

Code Snippet
public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate
            {
                //Get the List instance from the Fetaure Properties
                SPWeb oWeb = (SPWeb)properties.Feature.Parent;
                SPList oList = oWeb.Lists["Orders"];
                //Add event receiver definition to the 'Orders' List
                SPEventReceiverDefinition oDefinition = oList.EventReceivers.Add();
                oDefinition.Assembly = Assembly.GetExecutingAssembly().FullName;
                oDefinition.Class = "EventReceiverDemo.OrdersEventReceiver.OrdersEventReceiver";
                oDefinition.Type = SPEventReceiverType.ItemAdded;
                oDefinition.SequenceNumber = 10005;
                oDefinition.Name = "OrdersEventReceiverItemAdded";
                oDefinition.Data = null;
                oDefinition.Update();
            });
        }

15) Added the following code in the FeatureDeactivating event. We need to remove the event receiver definition from SPEventReceiverDefinitionCollection.

Code Snippet
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate
            {
                //Get the List instance from the Fetaure Properties
                SPWeb oWeb = (SPWeb)properties.Feature.Parent;
                SPList oList = oWeb.Lists["Orders"];
                //Remove event receiver definition from 'Orders' List
                SPEventReceiverDefinitionCollection oColl = oList.EventReceivers;
                foreach (SPEventReceiverDefinition oDefinition in oColl)
                {
                    if (oDefinition.Name == "OrdersEventReceiverItemAdded")
                    {
                        oColl[oDefinition.Id].Delete();
                        break;
                    }
                }
            });
        }

16) Now deploy the solution and activate the "OrderProcess" Feature.

17) Go to the "Orders" list and create a new item without entering the Shipping Address.

18) As shown in the following figure, the "ShippingAddress" field will be automatically updated.

19) If the "OrderProcess" Feature is deactivated then the event receiver will be removed and the "ShippingAddress" field will no longer be updated automatically.

Hope this post gives you a better idea about Event Receivers in SharePoint 2013.

1 comment: