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