Home > Development, SharePoint 2007 > HOWTO: Create an Event Handler for SharePoint(MOSS 2007)

HOWTO: Create an Event Handler for SharePoint(MOSS 2007)


As I see this question popping up on many forums, I thought it would be time to write a tutorial about it, even though there are already quite a few of them handling the subject.
Prerequisites:
How-to Create an Event Handler by making use of a feature:
To start with : what exactly is an event handler for SharePoint? It’s a piece of code that is triggered when something (an event!) happens. When that happens, our event handler can replace what is supposed to happen with our own code. How do we build that in Visual Studio (using WSP Builder)?
First of all, we will be creating a WSP Builder Project called MyEventHandler:
image
Once the project is created, we will right-click the project and select add new item. In the left column, select WSPBuilder and select Event Handler in the template list. In the name field I chose to call it DemoEventHandler.
image
You’ll get a new screen where you can define the scope of the feature. You can leave it at Web
image
After this step your project will have three additional files added to it and a few folders:
image
feature.xml: the CAML based declaration of your feature.
elements.xml: the CAML based declaration of the element(s) in your feature, which is your event handler in this case.
DemoEventHandler.cs : the code that will be overriding the existing SharePoint Event Handlers.
Let’s take a look at our feature.xml code:
<?xml version=
1.0 encoding=utf-8?>
<Feature Id=
875e92bb-782c-40b4-a5a9-f55423df667e
Title=
DemoEventHandler
Description=
Description for DemoEventHandler
Version=
12.0.0.0
Hidden=
FALSE
Scope=
Web
DefaultResourceFile=
core
xmlns=
<ElementManifests
>
<ElementManifest Location=
elements.xml/>
</ElementManifests
>
</Feature>
What this file does is identify the feature for SharePoint (Id), give it a title and description (which will be shown on the feature activation site), define a scope (where Web means site, where Site means Site Collection and then there is Web Application and Farm as possible scopes.
Another important part of the feature is the <ElementManifests> area. That area defines all the items that make part of the feature while the manifests themselves describe that specific part. As it is here the case with the event handler:
<?xml version=
1.0 encoding=utf-8 ?>
<Elements xmlns=
<Receivers ListTemplateId=
100>
<Receiver
>
<Name>
AddingEventHandler</Name>
<Type>
ItemAdding</Type>
<SequenceNumber>
10000</SequenceNumber>
<Assembly>
MyEventHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ca176e059473d6b1</Assembly>
<Class>
MyEventHandler.DemoEventHandler</Class>
<Data></Data
>
<Filter></Filter
>
</Receiver
>
</Receivers
>
</Elements>
What is important for us? First of all the ListTemplateId. The ListTemplateId defines to which List Types the Event Handler will be targeting. The table here below shows which list types there are available in SharePoint 2007:
ID Name
100 Generic list
101 Document library
102 Survey
103 Links list
104 Announcements list
105 Contacts list
106 Events list
107 Tasks list
108 Discussion board
109 Picture library
110 Data sources
111 Site template gallery
112 User Information list
113 Web Part gallery
114 List template gallery
115 XML Form library
116 Master pages gallery
117 No-Code Workflows
118 Custom Workflow Process
119 Wiki Page library
120 Custom grid for a list
130 Data Connection library
140 Workflow History
150 Gantt Tasks list
200 Meeting Series list
201 Meeting Agenda list
202 Meeting Attendees list
204 Meeting Decisions list
207 Meeting Objectives list
210 Meeting text box
211 Meeting Things To Bring list
212 Meeting Workspace Pages list
300 Portal Sites list
301 Blog Posts list
302 Blog Comments list
303 Blog Categories list
1100 Issue tracking
1200 Administrator tasks list
2002 Personal document library
2003 Private document library
Once we have defined which list we are going to target we will define that we are overriding an ItemAdding event. ItemAdding means that the event will be fired right before the item is added to the list. This allows us to modify the item before it is saved to the list. The other parameters aren’t that important at the moment, apart from the Assembly and Class that will be linking to the assembly that contains the code of your event handler.
Possible events that you can override:
ItemAdded
ItemAdding
ItemAttachmentAdded
ItemAttachmentAdding
ItemAttachmentDeleted
ItemAttachmentDeleting
ItemCheckedIn
ItemCheckedOut
ItemCheckingIn
ItemCheckingOut
ItemDeleted
ItemDeleting
ItemFileConverted
ItemFileMoved
ItemFileMoving
ItemUncheckedOut
ItemUncheckingOut
ItemUpdated
ItemUpdating
Ok, so we checked out the feature.xml and the elements.xml, but there is also the DemoEventHandler.cs file. That contains the actual code of our event handler:
using
System;
using
System.Collections.Generic;
using
System.Text;
using
Microsoft.SharePoint;
namespace
MyEventHandler
{
class DemoEventHandler : SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
}
public override void ItemAdding(SPItemEventProperties properties)
{
base.ItemAdding(properties);
}
public override void ItemUpdated(SPItemEventProperties properties)
{
base.ItemUpdated(properties);
}
public override void ItemUpdating(SPItemEventProperties properties)
{
base.ItemUpdating(properties);
}
}
}
If you deploy it like this your event handler will run, but it will just call the base class and nothing special will happen. Let’s change the ItemAdding Event (as it is already defined in our CAML to be deployed). We will change the itemadding event so that it will check, when an item is being added, by making sure the CheckValue column does not contain the string “dontadd”. If it does contain dontadd, an error message is displayed and the item is NOT added to the list. To do this, we modify the ItemAdding Event to this:
public override void ItemAdding(SPItemEventProperties properties)
{
if (properties.AfterProperties[“CheckValue”].ToString() == “dontadd”)
{
properties.ErrorMessage = string.Format(“The CheckValue column equals dontadd -> item will not be added.”);
properties.Status = SPEventReceiverStatus.CancelWithError;
properties.Cancel = true;
}
}
A little extra explanation. The AfterProperties contain the NEW values of an item. The BeforeProperties contain the OLD values of an item in case of an update. For an ItemAdding event the BeforeProperties are empty. What we do here is check the CheckValue properties value. If it contains “dontadd” we show the error message and by making use of properties.Status = SPEventReceiverStatus.CancelWithError we cancel the base.ItemAdding(properties) call. By adding properties.Cancel = true we cancel the Itemadding event.
Ok, so now we built this, but how do we get this working on our SharePoint site? With WSPBuilder that is quite easy. Rightclick on your project, select WSPBuilder / Build WSP. This will create a solution file to be deployed on your SharePoint farm. Once that is done, select WSPBuilder / Deploy and the solution will be installed and deployed to your farm.
image
Ok, one thing to note here is that the event handler will be targeting all lists. This means that every list that does not contain the CheckValue column will no longer work. But checking if the column exists is something that you should be able to do yourself. Once it is deployed to your SharePoint farm, create a new Custom List and Add the column CheckValue of type text. Then go to Site Settings, Site Features (NOT Site Collection Features as the scope was Web) and activate our newly deployed feature:
image
Ok, now we can test it by adding a new item with CheckValue equal to dontadd.
image
If you did everything according to plan, this is the information you should be receiving when you click ok:
image
Happy Coding!
In addition I added a few other interesting bits regarding Event Handlers
How-to Register an Event Handler through C# code:
The following code allows you to register an event handler by making use of code. RunWithElevatedPrivileges isn’t always necessary, but I added it to it so that you know that you can’t run the code in an application page as a user who doesn’t have the necessary rights.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
impersonateweb.AllowUnsafeUpdates = true;
_spListAanwezige.EventReceivers.Add(SPEventReceiverType.ItemAdded, “Namespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=61942ef99a051977”, “Namespace.EventClass”);
_ impersonateweb.AllowUnsafeUpdates = false;
});
How-to see if your event handler is deployed properly to the list:
Out of the box SharePoint doesn’t display if your event handler is correctly hooked to a list. I make use of SharePoint Inspector(http://www.codeplex.com/spi) to check out my SharePoint Farm. To see if something is hooked to your list go to the following structure in your SharePoint Inspector to check out which events are registered to your list:
image
Tags van Technorati: ,,
  1. Sheetal
    August 17, 2009 at 9:42 am

    great Article!!

    I have tried the exact steps but unfortunately the event is getting fired..
    even if i am adding a otem with CheckValue=dontadd, the item is getting added in the list…
    Can you please suggest me what might be going wrong?

    Thanks in Advance.

  2. koenvosters
    August 17, 2009 at 10:52 am

    Did you check if the eventhandler is connected to your list? (see last part of my article by using SharePoint Inspector?)
    Did you try debugging it? To debug it, attach it to the w3p process. That process will only exist if you already opened the website containing the list. Add a breakpoint to the event handler to see what is going wrong.
    If an error occurs it should also show in the Event Viewer.

  3. August 18, 2009 at 10:15 am

    1.Me too faced the same, but from VS it says successfully built, and deployed “Done!”

    2.It does not list the event handler in SP. (basically it does not get published)

    3.So i went on using this
    http://www.wssdemo.com/Lists/Resources/DispForm.aspx?ID=731

    4.just for deployment. Great Success!, no extra step, just point the location
    and add the event handler, by giving your class name, sequence, type.

    5.and the i used the inspector as mentioned above now it shows the event handled.
    6.and then i tested the event handler work. it did work, but few clarifications will post separately.

    Thank you for wonderful tool put to gether.

    sahridhayan

    • koenvosters
      August 18, 2009 at 11:32 am

      Are you sure you activated the feature?

      • August 19, 2009 at 9:18 am

        Hi,

        I did not find the feature listed as you pointed out (because i have done this for a Document Library). Hope it is a different take?

        But i tested like this it works.

        1. i went to the document library, click “New” button for creating a new document.
        2. Word opens, and i typed content, save-> prompt -> enter value “CheckValue” i give
        “dontadd” it stops me from saving. If i give any other value i allows to save.
        3. I went an uploading a document, it prompts, but does not stop, it allows to save for any value.
        4. i edited the 1st document, in word, and saved, again prompts, this time no stopping!

        bit confused.

        any direction which step is lost?

        thanks,
        sahridhayan

  4. August 19, 2009 at 9:20 am

    Just want to add few more info,
    in either sitecollection features and site features. i dont feature (Event handler listed)
    i am using WSS 3.0

  5. sheetal
    August 21, 2009 at 10:11 am

    Thanks koenvosters!

    I have tried debugging it and foundout that this line :
    if (properties.AfterProperties[“CheckValue”].ToString() == “dontadd”)
    was throwing an exception :
    System.NullReferenceException was unhandled by user code
    Message=”Object reference not set to an instance of an object.”

    I couldn’t find the reason of this exception but i uninstalled and build and deployed again, it worked for me.

    Sahridhayan : I have tried this for both list and document Library..worked fine for me.
    If in the feature.xml , the scope is given as ‘Web’ , you will find the eventhandler at site features level, if you give it as ‘Site’ , you will need to activate it from the sitecollection features page.

  6. koenvosters
    August 21, 2009 at 12:33 pm

    Yes, if that happens it means it can’t find your CheckValue column. Take into account that CheckValue is case sensitive :p
    A good check would be to make sure that it is not null, but that was not the point of my post 🙂 Glad you figured it out.

  7. August 31, 2009 at 7:37 am

    Hi,

    for both of you some update.

    At site level we cannot attach event handler is the issue which i faced,

    visit this link for more information.

    http://social.msdn.microsoft.com/forums/en-US/sharepointdevelopment/thread/e932cbb9-186c-4150-acd3-86af494401af

    Thanks for input,

    sahridhayan

  8. Edward
    October 5, 2010 at 1:39 pm

    I am having same issue as Sahridhayan. I set the scope to “Site” rather than “Web” because I need the handler available for the whole site collection. I ran build WSP and Deploy. However the handler did not show up in the list of features for either the site or the site collection.

    • Edward
      October 5, 2010 at 2:05 pm

      OK went to forum link provided by Sahridhayan and understood the point he was making i.e. It is not possible to attach an event handler feature at the site collection level. (This is going to screw us royally). Interestingly enough, neither the WSP Builder or the compile (build) added the assembly to the GAC. I had to use the menu item “Copy to GAC” explicitly to get assembly to GAC. First time that has happened.

  9. Edward
    October 5, 2010 at 2:19 pm

    Unable to attach event to list using Event Handler Manager which delivers error saying unable to load class. Handler never fires.

  10. Sandip Nirmal
    October 15, 2010 at 5:17 am

    I am getting an error when trying to “Build WSP”. Here is the error…
    “Could not load file or assembly ‘CabLib, Version=10.2.0.0, Culture=neutral, PublicKeyToken=5c838b77b53f84a0’ or one of its dependencies. The system cannot find the file specified.”

    What could be the reason?

    Thanks in advance.

  11. Dinesh
    November 22, 2010 at 1:23 pm

    After Modifying the ItemAdding method while right clicking on my project I am not getting WSP Builder option.So can someone help me on this?

  12. Koen Vosters
    May 18, 2011 at 3:53 pm

    Dinesh, did you install wspbuilder?

  13. May 14, 2012 at 11:16 am

    Hi, Where do I get the WSPBuilder template. When I open visual studio and highlight SharePoint I don’t see WSPBuilder.

    • koenvosters
      May 15, 2012 at 11:46 am

      WSPBuilder can be found on codeplex.

  1. No trackbacks yet.

Leave a reply to sahridhayan Cancel reply