Thursday 19 March 2015

Event Handlers in SharePoint



Overview:
What is a custom event handler? A custom event handler is a .Net assembly that contains the additional business logic you need to run when the event occurs in SharePoint.
Event handlers allow you to add [SOMETHING] your business needs into the functionality of SharePoint. [SOMETHING] examples:
1.       Retrieve information from a database such as filling in the remaining fields of a list based on a CustomerID (assuming you don't have an enterprise license for BDC)
2.        Call a web service
3.        Start a workflow
4.        Perform list data validation
5.       Convert document to PDF and store in alternative list.
6.       Access data in another list
Event Types:
a.       Microsoft.SharePoint.SPWebEventReceiver : "Site Level"
Occurs after a site collection has been deleted.
Occurs when a site collection is being deleted.
Asynchronous Afterevent that occurs after an existing Web site is completely deleted.
Synchronous before event that occurs before an existing Web site is completely deleted.
Asynchronous after event that occurs after an existing Web site has been moved.
Synchronous before event that occurs before an existing Web site has been renamed or moved to a different parent object.


b.      Microsoft.SharePoint.SPListEventReceiver : "List Level"

Occurs after a field link is added.
Occurs when a field link is being added to a content type.
Occurs after a field has been removed from the list.
Occurs when a field is in the process of being removed from the list.
Occurs after a field link has been updated
Occurs when a field link is being updated

c.        Microsoft.SharePoint.SPItemEventReceiver : "List Item Level"

Asynchronous After event that occurs after a new item has been added to its containing object.
Synchronous before event that occurs when a new item is added to its containing object.
Asynchronous after event that occurs after a user adds an attachment to an item.
Synchronous before event that occurs when a user adds an attachment to an item.
Asynchronous after event that occurs when after a user removes an attachment from an item.
Synchronous before event that occurs when a user removes an attachment from an item.
Asynchronous after event that occurs after an item is checked in.
Asynchronous after event that occurs after an item is checked out.
Synchronous before event that occurs as a file is being checked in.
Synchronous before event that occurs after an item is checked out.
Asynchronous after event that occurs after an existing item is completely deleted.
Synchronous before event that occurs before an existing item is completely deleted.

Occurs after a file is moved.
Occurs when a file is being moved.
Synchronous before event that occurs when an item is being unchecked out.
Synchronous before event that occurs when an item is being unchecked out.
Asynchronous after event that occurs after an existing item is changed, for example, when the user changes data in one or more fields.
Synchronous before event that occurs when an existing item is changed, for example, when the user changes data in one or more fields.


Asynchronous vs Synchronous Events: The "ing" and the "ed"
As you might have noticed above, there are two events raised for each type of event. The "...ing" event occurs before the action starts and the "...ed" occurs after the actions ends. "...ing" events occur synchronously while the "...ed" events occur asynchronously. What does this mean?

Synchronous events:
·         Occur before the event.
·         Block the flow of code execution until your event handler completes.
·         Provide you with the ability to cancel the events resulting in no after event (“...ed") being fired.

Asynchronous events:
·         Occur after the event.
·         Do not block the flow of code execution in SharePoint.

When building custom event handlers, keep the following points in mind:
1. Security:
The assembly you deploy to the Global Assembly Cache(GAC) is running with full trust. Watch out for the following:
 Denial of Service attack: If a user uploads 10000 items to a list, what is the effect it will have to the systems your assembly uses.
SQL Injection attack: If a user attempts to insert SQL statements into a column of a list that your assembly uses to update a database, what mechanisms are you using to make sure the input is valid.
Cross Site scripting attack: What is the effect of adding script to a column that your assembly uses to update another area in SharePoint?
2. Performance:
Watch out for the following:

Load: What burden are you placing on your web front end servers to run the assembly each time an event occurs? Use performance counters to determine this.
Long Running Operations: Consider creating a custom SharePoint timer job. Kick off/ Schedule the Timer Job from the event rather than running all the logic inside the event. This will allow you to use the features of SharePoint to view whether the Timer Job ran successfully.
Sync vs Async Events: Synchronous events have to wait until your code completes before returning the page, whereas Asynchronous events show the page immediately.
3. Error Handling:
When using synchronous events and you decide to cancel an event, let the user know why the event was cancelled. For example, update a Task List with a message why it failed.
Log your errors so that you can determine what issue is occurring when your system is in production environment.
4. Connections: Cater for external systems being down when you are trying to connect to them. Don’t let your code / solution go belly up because you cannot connect to a database.
5. Bulk Operations:
The MSDN documentation mentions that event handlers will not fire when bulk operation is occurring. For example, when a new list is created, the FieldAdding event will not fire. 
Limitations of Event Handler in SharePoint
Strangely there is no “SiteAdding”, “SiteAdded” event. However, if you really need this event you could create a “feature” to accomplish this. Features in SharePoint have a “FeatureActivated” event, where you could perform an action on creation of a site.
Building Event Handlers for SharePoint
Steps:

Use the following steps if you want to create your solution from scratch otherwise download the starter kit and continue from Step 7.

1)   Open Visual Studio 2005.

2)   Create a new class library project.

3)   Reference the Microsoft.SharePoint assembly.

4)   Rename the default class to the name you want to give your event handler class. E.g. ItemHandler

5)   Add your “using” statement: “using Microsoft.SharePoint;”

6)   Inherit from the following SharePoint base classes depending on what type of event handler your want to create:
a.   Site                      : SPWebEventReceiver
b.   List Columns    : SPListEventReceiver
c.   List Items           : SPItemEventReceiver
d.   Email                   : SPEmailEventReciever

7)   In your class, type “override” and let IntelliSense provide you with a list of events to override.

8)   Implement the logic in the overridden method(s).

9)   Compile, fix errors, recompile until build succeeds.

10)       Strongly name your assembly ( sign your assembly )
a.   Right Click your Class Library Project
b.   Select Signing Tab
c.   Choose a strong name key file:
                                         i.    <browse> = select a previously created key file.
                                        ii.    <new> = create a new key file.

Overview
So you have deployed the assembly to the farm, now what? How do I register an event in your assembly for a Site, List, or Content Type?

I will describe three ways to deploy your assembly’s events.

1) Manage EventReceivers via Code
2) Deploy event handlers using the Feature framework of MOSS 2007
3) A cool custom Site Settings Application I built to manage (view, add, edit and delete) event handlers.



Managing EventReceivers via Code
The site (SPWeb) object, the list (SPList) object and the Content Type (SPContentType) object expose a collection called EventReceivers based on the SPEventReceiverDefinitionCollection class.
This collection maintains a set of SPEventReceiverDefinition objects (events) attached to a site, list or content type.
Adding Event Handlers (SPEventReceiverDefinition)
This class provides an “Add” method to attach a new SPEventReceiverDefinition (We created and deployed these to MOSS in Post 1 and 2.) The Add method asks for three bits of information:
SPEventReceiverType: This tells SharePoint the type of event receiver we are adding to the EventReceiver collection.
Assembly name: The name of the assembly. E.g. “Litwarehandlers, Version 1.0.0.0, Culture=neutral, PublicKeyToken=a6ab42c509981682”
Class name: The name of the class. E.g. “Litwarehandlers.SiteHandlerClass”
Once attached, the site, list or content type will now start picking up these events and executing your assemblies code.
Modifying Sequence Numbers
Another important property you may want to set for each event you attach is the Sequence Number. The sequence number determines the order your event assemblies’ fire. This is especially important when you have created multiple assemblies that are all attached to the same Site, List or Content Type event. 
To modify the Sequence Number, you need to retrieve the SPEventReceiverDefinition object from the EventReceivers collection.
Site: site.EventReceivers
List: list.EventReceivers
Content Type: site.ContentTypes[content type name].EventReceivers
A suggested best practice (and only my opinion), do not use sequence numbers below 10000 as SharePoint uses event handlers extensively to run SharePoint Workflows, etc. These event handlers use Sequence Numbers, starting at 1000.
Deleting Event Handlers (SPEventReceiverDefinitions)
When removing definitions, here is what you have to do:
Site:
Attach to the site (SPWeb)
Lookup the SPEventReceiverDefinition object in the site.EventReceivers collection.
Use the delete method of the SPEventReceiverDefinition object to remove it from the collection.
Call the site.Update() method.

List:
Attach to the site (SPWeb)
Retrieve the list : (site.Lists[GUID or listname])
Lookup the SPEventReceiverDefinition object in the list.EventReceivers collection.
Use the delete method of the SPEventReceiverDefinition object to remove it from the collection.
Call the list.Update() method.

Content Types:
Attach to the site (SPWeb)
Retrieve the SPContentType (site.ContentTypes[SPContentTypeId])
Retrieve the SPEventReceiverDefinition object : (SPContentType.EventReceivers[GUID])
Use the delete method of the SPEventReceiverDefinition object to remove it from the collection.
Call the SPContentType.Update() method.
Managing assemblies using Features
It is possible to create a feature that deploys your event handler to the assembly.
MSDN has an example on how to achieve this: http://msdn2.microsoft.com/en-us/library/ms453149.aspx
See screenshot of the xml you need to write to deploy an event via the features framework:

Limitations:
·         It is difficult to see what event handlers are installed and the sequence they are firing for a site, list or content type. To modify, requires rebuilding the feature with the correct settings.
·         Using a feature, “hardcodes” the event handler to an individual list or Content Type. Each time you want to use the SAME event handler, you are forced to write another feature to register it.


No comments:

Post a Comment

Hide Time from events in Calendar list or webpart Use below code in content edit webpart or by editing list page in SharePoint designer ...