How to Create Event Receivers for Windows SharePoint Services 3.0

You'll be surprised how often that you'll use event receivers instead of Workflow in order to implement functionality in Sharepoint; And who better to get you started with a simple guide to using them than Charles Lee?

In this article, which is part of a series on Windows SharePoint Services (WSS) 3.0, I am going to show you how to create a component called an event receiver.  An event receiver is essentially a piece of code which can be attached to a specific SharePoint object; it will be executed whenever a specified event occurs within that object.  An example might be something that executes whenever an item is created in a specific list.

In many cases a project that might at first seem to be a workflow is actually better suited to being implemented with an event receiver. This is  because simple actions such as validation of input data, verification and data processing can be performed quickly and smoothly with an event receiver.  Event receivers are also typically used for initiating additional external business processes.

At this point you are probably already realising that event receivers provide a developer with a good way to add extra functionality at a specific point (or variety of points) within the SharePoint environment and therefore ‘extend’ the functionality of the native SharePoint environment in a way which is supported by Microsoft.

Event receivers can, for example, be attached to instances of the SPSite, SPList and SPListItem classes.  An event receiver will execute either before or after the specified event occurs.  ‘Before events’ are synchronous and can be used to cancel the event entirely whereas ‘After events’ are asynchronous and therefore cannot have any impact on the event because it  has already occurred by then. 

In order to create an event receiver you have to create a specific class: In truth you have to inherit a very specific base class.  Each of the base classes contains an overridable method for each event.  If you override this method with your custom code then this is what will be executed when that event is raised.  The four base classes are:

  • SPWebEventReceiver
  • SPListEventReceiver
  • SPItemEventReceiver
  • SPEmailEventReceiver

The first three are the main base classes for working with site, list and item events.  The email event receiver is specifically for use on email enabled lists.  The method-overrides that are available to you within these main event receiver base classes are outlined in the table below.  You must override the appropriate base class for the methods which you wish to implement.

SPWebEventReceiver

Event

Execution

SiteDeleting

Synchronous

WebDeleting

Synchronous

WebMoving

Synchronous

SiteDeleted

Asynchronous

WebDeleted

Asynchronous

WebMoved

Asynchronous

SPListEventReceiver

Event

Execution

FieldAdding

Synchronous

FieldUpdating

Synchronous

FieldDeleting

Synchronous

FieldAdded

Asynchronous

FieldUpdated

Asynchronous

FieldDeleted

Asynchronous

SPItemEventReceiver

Event

Execution

Item Adding

Synchronous

ItemUpdating

Synchronous

ItemDeleting

Synchronous

ItemAdded

Asynchronous

ItemUpdated

Asynchronous

ItemDeleted

Asynchronous

ItemAttachmentAdded

Asynchronous

ItemAttachmentDeleted

Asynchronous

ItemCheckedIn

Asynchronous

ItemCheckedOut

Asynchronous

ItemFileConverted

Asynchronous

ItemFileMoved

Asynchronous

ItemUncheckedOut

Asynchronous

Creating an event receiver

To show how to create an event receiver, I am going to implement a piece of code that renames any document uploaded to a document library to its ID, and the original filename is then used as the title of the document.  This can be useful as it keeps the URL length for your documents nice and short.

We need to override the ItemAdded method of the SPItemEventReceiver. This will allow the code to execute asynchronously so that  the code execution will not block the UI whilst it takes place.

Note:  I am using Visual Studio 2008 with the WSPBuilder extensions installed.

  1. Open Visual Studio 2008, and select File > New > Project.    
  2. Select a Class Library, and select an appropriate name and location.

    Please ensure that your assembly is signed, your project references the WSS 3.0 dll and that you have a 12 folder set-up with a single feature folder as shown below (you will only need the 12, TEMPLATE and FEATURES folders not the others)

    927-image002.jpg 

  3. Right-click on your project and select Add > New Item. 
  4. Select Class and then choose an appropriate name for your event receiver.  Click Add.
  5. Open up your event receiver code file.
  6. Import the Microsoft.SharePoint namespace and set the class to inherit from SPItemEventReceiver

     

     

  7. Add a new method to override the

ItemAdded method of the base class. Add the following code to this method to allow documents to be renamed when they are uploaded.

Essentially this code is saving the name of the original file (minus its file extension) and then using this information as the Title of the document.  The name of the document (which is stored internally as FileLeafRef by SharePoint) is then saved as the ID of the relevant item in the document library using the same file extension as the original. 

The benefit of this is that if I upload a document called ‘Product Specification 1.pdf’, the URL to this could then become as short as http://toasterhouse/docs/1.pdf.  Anyone who has had to deal with the 255 character limit for URLs will see the point. .Right-click on the feature folder and rename this to something sensible, as this will be the name of your SharePoint feature.  I used ‘DocumentRenamer’ Right-click on your feature folder and select Add > New Item.  Select XML file and call this feature.xml  The feature.xml file contained in the feature folder will now need to be changed to reflect your feature requirements.

You will need to ensure that the [GUID] is replaced with a valid GUID without the braces { }.  

Right-click on your feature folder and select Add > New Item.  Select XML file and call this elements.xml  The elements.xml file contained in the feature folder will also need to be changed to reflect your feature requirements.  Essentially you want to bind your event receiver to a list or library, or to many lists and libraries.  In our case we are going to bind to all document libraries within our site (SPWeb.)

 

 

It may be that, in your application, you wish to bind your event receiver to a specific list instance.  In this case you can write an SPFeatureReceiver in order to bind your event receiver to the appropriate list instance when the feature is activated.

The Assembly element of the receiver will need to be a fully qualified reference to the assembly which contains your event receiver, and the Class element will need to include the root namespace of your project.

The ListTemplateId attribute specifically refers to the ID for document libraries which is 101.  Other ListTemplateId values can be found by browsing the SharePoint documentation on MSDN.  

The infrastructure required for your feature is now complete.  It is at this point that  the benefits of using WSPBuilder for your packaging and deployment will become obvious.  To build and package your WSP file, simply right-click the project and select WSPBuilder > Build WSP.

927-image004.jpg
You will now have a compiled and packaged WSP file at the root of your project. To deploy this solution to your development farm simply right-click the project file and select WSPBuilder > Deploy.  Once this operation is complete you can then visit a site on your development SharePoint installation and activate the feature:

927-image006.jpgIf you upload a document to any document library on this site then you will notice that the event receiver has executed the code and made the required changes.  Although this is an asynchronous action so you will not notice it straight away. 

 

This example has demonstrated the power of an event receiver.  Essentially the code that you execute can perform any action that you can think of by implementing the WSS 3.0 object model or any other 3rd party programming interface. 

Workflow or Event Receiver?

If you need some action to happen in response to an action undertaken in SharePoint, then you have two choices:  you could develop a workflow (as detailed in my previous two articles) or you could create an event receiver.  If there is no cause for any kind of human interaction in the process required then you should probably looking to the event receiver model to implement this.  However if the action is going to involve a human decision or interaction then you should be looking to implement it as a workflow.

It is worth bearing in mind that workflows are handled by the SharePoint workflow engine built on top of Windows Workflow Foundation and that there is a lot of core code and functionality which is kicked off in support of a running workflow instance which is not required in order to implement an event receiver.  If you don’t need all those bells and whistles then steer clear of workflow as it may be an unnecessary performance drain!

Hopefully this article has helped you to see the benefits of implementing a solution via an event receiver.  As I have mentioned before it all too easy for a project to end up as a workflow when actually what was required was an event receiver.

Next time I plan to take a deeper dive into writing custom SharePoint code by looking at the feature framework and how you can use it to leverage custom code in SharePoint.

For previous articles in this series on using SharePoint Services see

How to Create Custom Lists in Windows SharePoint Services 3.0

 

How to Create Custom Workflows in Windows SharePoint Services 3.0

 

How to Create Custom SharePoint Workflows in Visual Studio 2008