Click here to monitor SSC
Av rating:
Total votes: 20
Total comments: 3


Charles Lee
How to Create Event Receivers for Windows SharePoint Services 3.0
28 January 2010

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)

     
  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
    Imports Microsoft.SharePoint


    Public Class RenameUploadedDocuments
         Inherits SPItemEventReceiver

     

    End Class
     

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

    Dim strOriginName As String = properties.ListItem.File.Name

    Dim strExt As String = strOriginName.Split(".")(1)

    Dim strDocTitle As String = _

        strOriginName.Replace("." & strExt, "")

    Dim strNewName As String = _

        properties.ListItemId.ToString & "." & strExt

    Dim checkInRequired As Boolean = False

    Dim item As SPListItem = properties.ListItem

     

    If item.File.CheckOutStatus = _

        SPFile.SPCheckOutStatus.None Then

        item.File.CheckOut()

        checkInRequired = True

    End If

     

    item("Title") = strDocTitle

    item("FileLeafRef") = strNewName

    item.Update()

     

    If checkInRequired Then

        item.File.CheckIn("Document renamed", _

            SPCheckinType.MinorCheckIn)

    End If

    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.
  9. .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’
  10. Right-click on your feature folder and select Add > New Item.  Select XML file and call this feature.xml 
  11. The feature.xml file contained in the feature folder will now need to be changed to reflect your feature requirements.
    <?xml version="1.0" encoding="utf-8" ?>

    <Feature

            Id="[GUID]"

            Title="Document Rename on Upload"

         Description="Renames all documents on upload to their ID

    in order to reduce URL length."

            Scope="Web"

            xmlns="http://schemas.microsoft.com/sharepoint/">

     

            <ElementManifests>

                 <ElementManifest Location="elements.xml"/>

            </ElementManifests>

     

    </Feature> 

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

  12. Right-click on your feature folder and select Add > New Item.  Select XML file and call this elements.xml 
  13. 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.)

    <?xml version="1.0" encoding="utf-8" ?>

    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">

     

      <Receivers ListTemplateId="101">

     

        <Receiver>

         <Name>Item_Added_Event</Name>

         <Type>ItemAdded</Type>

         <SequenceNumber>1000</SequenceNumber>

    <Assembly>

    CodeStorm.SharePoint.EventReceivers.RenameUpload, Version=1.0.0.0, Culture=neutral,

    PublicKeyToken=062fbcc1f4131ad6

    </Assembly>

    <Class>

    CodeStorm.SharePoint.EventReceivers.RenameUpload.RenameUploadedDocuments

    </Class>

        </Receiver>

       

      </Receivers>

     

    </Elements>

    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.  

  14. 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.


  15. You will now have a compiled and packaged WSP file at the root of your project.
  16. 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:

  17. If 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



    • This article has been viewed 10848 times.
      Charles Lee

      Author profile: Charles Lee

      Charles Lee is a SharePoint Subject Matter Expert for Capgemini UK. He was originally a .NET web developer, but currently focuses on best practice and guidance for SharePoint solutions to complex business problems (though he still gets hands-on with some code every once in a while.). Check out his blog for more information.

      Search for other articles by Charles Lee

      Rate this article:   Avg rating: from a total of 20 votes.


      Poor

      OK

      Good

      Great

      Must read
       
      Have Your Say
      Do you have an opinion on this article? Then add your comment below:
      You must be logged in to post to this forum

      Click here to log in.


      Subject: This is just what I'm looking for but need help!
      Posted by: Anonymous (not signed in)
      Posted on: Wednesday, February 10, 2010 at 4:13 PM
      Message: This is what I need, I am more experienced with Sharepoint and SPD, but not VS 08. Can you please give me some more help on how to build this project?

      Subject: Re: This is just what I'm looking for but need help!
      Posted by: CharlesLee (view profile)
      Posted on: Friday, February 12, 2010 at 2:45 AM
      Message: What part are you stuck on?

      If you need help with setting up the initial visual studio project then go to MSDN and look up things like 'how to sign an assembly' and 'how to reference an assembly'. The folder structure is just a case of adding new folders to your project that match the image.

      Remember you need to have the WSPBuilder Extensions installed for step 14.

      Subject: Need help also
      Posted by: Richard Sigar (view profile)
      Posted on: Thursday, September 08, 2011 at 12:42 PM
      Message: What if I'm trying to add a text string to the new document name in addition to the auto generated number?

      Basically I want my documents to be named like this:

      XXX_NUMBERSEQUENCE

      Thank you

       






      recommended site pinvoke

      PInvoke.net is a user-driven wiki which provides .NET developers with native method signatures, so they don't have to spend time writing them from scratch.




      TortoiseSVN and Subversion Cookbook Part 3: In, Out, and Around
       Subversion doesn't have to be difficult, especially if you have Michael Sorens's guide at hand. After... Read more...

      Feature Usage Reporting in Early Access Programs
       After doing Web development, you can get very used to the luxury of having basic information about your... Read more...

      Feature Usage Reporting in Early Access Programs
       After doing Web development, you can get very used to the luxury of having basic information about your... Read more...

      TLS/SSL and .NET Framework 4.0
       The Secure Socket Layer is now essential for the secure exchange of digital data, and is most generally... Read more...

      SmartAssembly: Eating Our Own Dogfood
       Quite often at Red Gate, we are some of our own most enthusiastic software-users. SmartAssembly is a... Read more...

      A Complete URL Rewriting Solution for ASP.NET 2.0
       Ever wondered whether it's possible to create neater URLS, free of bulky Query String parameters?... Read more...

      Visual Studio Setup - projects and custom actions
       This article describes the kinds of custom actions that can be used in your Visual Studio setup project. Read more...

      .NET Application Architecture: the Data Access Layer
       Find out how to design a robust data access layer for your .NET applications. Read more...

      Web Parts in ASP.NET 2.0
       Most Web Parts implementations allow users to create a single portal page where they can personalize... Read more...

      Configuring Forms Authentication in SharePoint 2007
       Damon Armstrong provides a step-by-step guide to the processes, quirks and pitfalls of setting up... Read more...

      Over 400,000 Microsoft professionals subscribe to the Simple-Talk technical journal. Join today, it's fast, simple, free and secure.

      Join Simple Talk