Monday 9 April 2012

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=
http://schemas.microsoft.com/sharepoint/>
<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=
http://schemas.microsoft.com/sharepoint/>
<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:

IDName
100Generic list
101Document library
102Survey
103Links list
104Announcements list
105Contacts list
106Events list
107Tasks list
108Discussion board
109Picture library
110Data sources
111Site template gallery
112User Information list
113Web Part gallery
114List template gallery
115XML Form library
116Master pages gallery
117No-Code Workflows
118Custom Workflow Process
119Wiki Page library
120Custom grid for a list
130Data Connection library
140Workflow History
150Gantt Tasks list
200Meeting Series list
201Meeting Agenda list
202Meeting Attendees list
204Meeting Decisions list
207Meeting Objectives list
210Meeting text box
211Meeting Things To Bring list
212Meeting Workspace Pages list
300Portal Sites list
301Blog Posts list
302Blog Comments list
303Blog Categories list
1100Issue tracking
1200Administrator tasks list
2002Personal document library
2003Private 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

No comments:

Post a Comment

Note: only a member of this blog may post a comment.