Overview
Microsoft Visual Studio 2010 provides a project type
that enables you to build event receivers that perform actions before or after
selected events on a Microsoft SharePoint 2010 site. Often, real SharePoint solutions need to catch
events and user actions to subsequently
execute some custom code.
Whenever you need to start business processes related to such
events and user actions, you
would probably need to develop custom workflows
However there are many situations in which a
workflow is overkill.
In such cases, it suffices to
execute a small piece of code that executes quickly and might not
always be critical to the
business. Suppose, for example, that you want to trigger an event
just after a document check-out
user action. In this situation, you can define a custom event
receiver that executes your
custom code whenever the check-out operation happens.
To satisfy these situations,
Microsoft SharePoint 2010 provides a standard way to develop
event receivers (known in early
SharePoint versions as event sinks), by inheriting from common
base classes and
registering the corresponding libraries into the target environment.
Event Receiver Targets
You
can create event receiver classes and override specific events by using visual
studio 2010 templates for SharePoint 2010. You can add event receivers for
following types of objects in SharePoint 2010:
§ List items
§ E-mails received by lists
§ Workflows attached to lists
§ List objects
§ Webs
§ Features
Item-Level Event
Receivers
The
events related to SPListItem instances are defined in classes that inherit from
SPItemEventReceiver.
The Events Provided
by the SPItemEventReceiver
Base Class
ItemAdded
Occurs after an item has been added to a list.
ItemAdding
Occurs before an item is going to be added to a list.
ItemAttachmentAdded
Occurs after an attachment has been added to a list item.
ItemAttachmentAdding
Occurs before an attachment is going to be added to a list item.
ItemAttachmentDeleted
Occurs after an attachment has been deleted from a list item.
ItemAttachmentDeleting
Occurs before an attachment is going to be deleted from a list item.
ItemCheckedIn
Occurs after an item has been checked into a list.
ItemCheckedOut
Occurs after an item has been checked out from a list.
ItemCheckingIn
Occurs before an item is going to be checked into a list.
ItemCheckingOut
Occurs before an item is going to be checked out from a list.
ItemDeleted
Occurs after an item has been deleted from a list.
ItemDeleting
Occurs before an item is going to be deleted from a list.
ItemFileConverted
Occurs after a file has been converted using document conversion
services.
ItemFileMoved
Occurs after an item has been moved.
ItemFileMoving
Occurs before an item is going to be moved.
ItemUncheckedOut
Occurs after an item has been unchecked out from a list.
ItemUncheckingOut
Occurs before an item is going to be unchecked out from a list.
ItemUpdated
Occurs after an item has been updated from a list.
ItemUpdating
Occurs before an item is going to be updated from a list.
ContextEvent The item received a context event.
The Main Members of
the SPEventPropertiesBase Class
EventType
Describes the kind of event that occurred, using a SPEventReceiverType event
type
enumeration.
EventUserToken
Corresponds to the current user token (SPUserToken) at the time the event is
fired.
OriginatingUserToken
Corresponds to the user token (SPUserToken) of the user that makes the
request.
Cancel
Boolean property with which you cancel the current event in Before events.
ErrorMessage
The error message that will be displayed to the end user if the event is
cancelled.
Status
Defines the status (SPEventReceiverStatus) of the current event. It can assume
values
of: Continue, to continue with the event; CancelNoError, to cancel the
event
without throwing any kind of error; CancelWithError, to cancel the
event
and throw an error; CancelWithRedirectUrl, to cancel the event and
redirect
the user to a specific RedirectUrl.
RedirectUrl
Defines the URL to redirect the user to, when the Status value is
CancelWithRedirectUrl.
SiteId
Returns the ID of the SPSite that contains the event source list item.
ReceiverData
Returns a String that represents the configuration of the current event
receiver
instance.
The members of the SPItemEventProperties implementation.
The Main Members of the SPItemEventProperties Class
InvalidateListItem
Invalidates (sets the corresponding variable to NULL) the list item that
represents
the
source of the event.
InvalidateWeb
Invalidates (sets the corresponding variables to NULL) the list item, the
list,
and the website that represent the source of the event. Internally, this
method
also disposes of the SPWeb instance related to the event, if any
such
instance exists.
OpenSite
Returns an instance of the SPSite that corresponds to the current event
source,
impersonating the current user at the time the event is fired, if any
user
is available; otherwise, it uses the current user.
OpenWeb
Returns an instance of the SPWeb corresponding to the current event
source,
impersonating the current user at the time the event is fired, if any
user
is available; otherwise, it uses the current user.
Dispose
Disposes the current SPSite and SPWeb instances. Internally, it also invokes
the InvalidateWeb
method.
CurrentUserId
Returns the ID of the user who caused the event to fire.
UserDisplayName
Returns the DisplayName of the user who caused the event to fire.
UserLoginName
Returns the LoginName of the user who caused the event to fire.
AfterProperties
References a hash table of tuples (String/Object) describing the properties
(columns)
of the source list item after the event occurred.
AfterUrl
Represents the URL of the source list item after the event occurred. For
item
file rename or move operations, this is the new file name.
BeforeProperties
References a hash table of tuples (String/Object) describing the properties
(columns)
of the source list item before the event occurred.
BeforeUrl
Represents the URL of the source list item before the event occurred. For
item
file rename or move operations, this is the old file name.
List Returns
a reference to the SPList that contains the event source list item.
ListId
Returns the ID of the list that contains the event source list item.
ListItem
Returns a reference to the SPListItem that represents the event source item.
ListItemId
Returns the ID of the event source item.
ListTitle
Returns the Title of the list that contains the event source list item.
Web Returns
a reference to the SPWeb that contains the event source item.
WebUrl
Returns the absolute URL of the SPWeb that contains the event source item.
RelativeWebUrl
Returns the server-relative URL of the SPWeb that contains the event
source
item.
Zone Returns
the Zone of the website that contains the event source list item.
Versionless
Provides the option to instruct SharePoint to handle the event without
List-Level Event
Receivers
Another
set of useful events are those related to lists. SharePoint offers a base class
named
SPListEventReceiver
with which you can trap changes to the fields of an existing list as well as
actions
related to adding or deleting lists instances.
FieldAdded
Occurs after a field has been added to a list definition.
FieldAdding
Occurs before a field is going to be added to a list definition.
FieldDeleted
Occurs after a field has been removed from a list definition.
FieldDeleting
Occurs before a field is going to be removed from a list definition.
FieldUpdated
Occurs after a field has been updated to a list definition.
FieldUpdating
Occurs before a field is going to be updated to a list definition.
ListAdded
Occurs after a new list has been added to a SPWeb instance.
ListAdding
Occurs before a new list is added to a SPWeb instance.
ListDeleted
Occurs after a list has been deleted from a SPWeb instance.
ListDeleting
Occurs before a list is deleted from a SPWeb instance.
As
with item-level events, all list-level events methods also receive a single
argument that
inherits
from SPEventPropertiesBase and represents the context of the event that will
occur
(Before)
or has occurred (After). For list-level events, the argument is a SPListEventProperties
type,
and provides the small set of members
InvalidateList
Invalidates (sets the corresponding variable to NULL) the list and/or the field
that
represents the source of the event.
InvalidateWeb
Invalidates (sets the corresponding variables to NULL) the list, the field, and
the
website that represent the source of the event. Internally, this method also
disposes
of the SPWeb instance related to the event, if any such instance exists.
Dispose
Disposes the current SPSite and SPWeb instances. Internally, it also invokes
the
InvalidateWeb
method.
FeatureId
Returns the GUID of the SharePoint feature that created the list instance for
ListAdding
and ListAdded event types.
FieldXml
Returns the XML definition of the field that is the source of the current
event.
List Returns
a reference to the SPList instance that is the source of the event.
ListId
Returns the ID of the SPList instance that is the source of the event.
ListTitle
Returns the Title of the SPList instance that is the source of the event.
TemplateId
Returns the ID of the list template that is related to the list instance that
is the
source
of the event.
UserDisplayName
Returns the DisplayName of the user who caused the event to fire.
UserLoginName
Returns the LoginName of the user who caused the event to fire.
Web Returns
a reference to the SPWeb that contains the event source list.
WebId Returns
a reference to the ID of the SPWeb that contains the event source list.
WebUrl
Returns the absolute URL of the SPWeb that contains the event source list.
Web-Level Event
Receivers
At the
web level, you can catch some events related to Site Collection deletion, both
before
and
after the action, and for website creation, deletion, moving, and provisioning.
To trap
such
events, you need to implement a custom class that inherits from SPWebEventReceiver.
.
The Events Provided
by the SPWebEventReceiver
Base Class
SiteDeleted
Occurs after a Site Collection has been deleted.
SiteDeleting
Occurs before a Site Collection is being deleted.
WebAdding
Occurs before an SPWeb is being added to a list collection.
WebDeleted
Occurs after an SPWeb has been removed from a Site Collection.
WebDeleting
Occurs before an SPWeb is going to be removed from a Site Collection.
WebMoved
Occurs after an SPWeb has been renamed or moved to another location.
WebMoving
Occurs before an SPWeb is being renamed or moved to another location.
WebProvisioned
Occurs after an SPWeb has been provisioned into a Site Collection.
Web-level
event receivers are usually most useful for enforcing custom policies, custom
layout
templates, or checking naming conventions, similar to list-events receivers.
Another
common use for web-level event receivers is to deny site or web deletion of
specific
websites—even
if the current user has the rights to provision and unprovision contents
and
sites. The unique argument for the web-level event receiver methods is of type
SPWebEventProperties,
which provides an entry point to the context Web, the context site,
and
their URLs.
The Main Members of
the SPWebEventProperties Class
InvalidateWeb
Invalidates (sets the corresponding variables to NULL) the website that
represents
the
source of the event. Internally, this method also disposes of the
SPWeb instance
related to the event, if any instance exists.
Dispose
Disposes of the current SPSite and SPWeb instances. Internally, it invokes the
InvalidateWeb
method.
FullUrl
Returns the absolute URL of the source Web on which the event occurred.
NewServerRelativeUrl
Represents the URL of the site after it has been moved.
ParentWebId
Returns the GUID of the current SPWeb instance.
ServerRelativeUrl
Represents the URL of the site before it has been moved.
UserDisplayName
Returns the DisplayName of the user who caused the event to fire.
UserLoginName
Returns the LoginName of the user who caused the event to fire.
Web Returns
a reference to the SPWeb that contains the event source list.
WebId Returns
a reference to the ID of the SPWeb that contains the event source
list.
Workflow Event
Receivers
SharePoint
provides workflow event receivers so that you can intercept events related to
running
workflows.
For instance, you can trap the WorkflowCompleted event to execute a custom
action
whenever a workflow instance completes
which
are provided by the base class, SPWorkflowEventReceiver.
The Events Provided
by the SPWorkflowEventReceiver Base Class
WorkflowCompleted
Occurs after a workflow instance is completed.
WorkflowPostponed
Occurs after a workflow instance has been postponed.
WorkflowStarted
Occurs after a workflow instance has been started.
WorkflowStarting
Occurs after a workflow instance is starting
The Main Members of
the SPWorkflowEventProperties Class
Member
Name Description
ActivationProperties
Represents the properties to start a new workflow instance. For example, it
contains
the InitiationData for the workflow. For further details about workflow
instances,
go to Part V, “Developing Workflows.”
AssociationData
Contains the workflow association data.
CompletionType
Contains information about the real outcome of the workflow. In fact, whenever
the
workflow completes, you can read the CompletionType property from
within
the WorkflowCompleted event. The property might have any of the following
values:
- Completed
- Errored
- ExternallyTerminated
- FailedOnStart
- InternallyTerminated
- NotApplicable
ErrorException
Returns the current exception instance, if defined.
InitiationData
Contains the workflow initiation data.
InstanceId
Represents the ID of the instance.
PostponedEvent
Signals whether the workflow has been postponed for Load or for Start.
RelativeWebUrl
Returns the relative URL of the SPWeb that contains the source.
TerminatedByUserId
The UserID of the user who terminated the workflow, for a terminated workflow
instance.
WebUrl
Returns the URL of the SPWeb that contains the source.
E-Mail Event
Receivers
The
e-mail event receivers support e-mail–enabled list instances, and allow you to
intercept
events
when the list receives e-mail messages. These event receivers are based on a
class
that inherits from SPEmailEventReceiver, and they
override the EmailReceived virtual method.
These events in event receiver classes are categorize
in to two categories. Those are before events and after events
Before events
Before events are synchronous events for which you can
write code, and have that code run before the operation that raised the event
has completed. The synchronous nature of before events, and the fact that the
operation has not yet completed, provides you with the ability to cancel the
event. By canceling an event, you can effectively cancel the operation that
raised the event. For example, you can cancel the adding, editing, or deleting
of a list item, and you can cancel the adding or deleting of a field in a list.
After events
After
events are asynchronous events for which you can write code, and have that code
run after the operation that raised the event has completed. The asynchronous
nature of after events, and the fact that the operation has already completed,
means that you cannot cancel the operation that raised the event; however, you
can be sure that all data changes associated with the event have completed when
your After-event handlers are raised.
In
this article I am going to discuss about how to create and deploy event
receiver for List item object using visual studio 2010.
Scenario
In this scenario, a secure sub site contains a list
named Job Definitions that
specifies allowed job titles for roles in the organization. Along with job
titles, the list also contains confidential salary information for the job
title and is therefore secured from users. In the main site, a list named Open Positions tracks
vacancies in the organization. You create two event receivers for the itemAdding and itemUpdating events
that verify that the title of the open position matches one of the approved
titles in the Job Definitions list.
Solution
Step 1: Create the Job Definitions sub site
1. On the main site, on the Site Actions menu,
click New Site
2. In the New Site dialog box, click Blank Site
3. On the right of the dialog box, click More Options
4. In the Title box, type Job Definitions
5. In the Web Site Address box, type JobDefinitions
6. In the Permissions section, click Use Unique Permissions, and then click Create
7. In the Visitors to this site section, select Use an existing group, and then selectHome Owners. Click OK.
Step 2: Create the Job Definitions list
1. In the New Site Select List from
left panel.
2. Then Click Create option to create a new List.
3. In the Create dialog box, Select Custom List.
4. In the Name box, type Job Definitions.
5. In the ribbon select List then Click Create Column.
6.Add
following columns to the list one by one, selecting given type within brackets.
§ Title (Default column)
§ MinSalary (Currency)
§ MaxSalar (Currency)
§ Role
Type (Choice: Permanent, Contract)
7.
Add few jobs to this list.
Note: The titles that you specify for each job that you
create because you will need them later.
Step 3:Create the Open Positions list
In the parent site, create a custom
list named Open Positions with the following columns:
Title (Default column)
Location (Single line of text)
Step 4: Create a SharePoint 2010 event receiver in
Visual Studio 2010
1.
Start Visual Studio 2010.
2On the File menu, click New, and then click Project
3. In the New Project dialog box, in the Installed Templates section, expand eitherVisual Basic or Visual C#, expand SharePoint, and then click 2010
4. In the template list, click Event Receiver
5. In the Name box, type VerifyJob
6. Leave other fields with their default values, and
click OK
7. In the What local site do you want to use for
debugging? List,
select your site.
8. Select the Deploy as a farm solution option, and then click Next
9. On the Choose Event Receiver Settings page, in the What type of event receiver do you want? List, select List Item Events
10. In the What Item should be the event source? List, select Custom List
11. Under Handle the following events select the An item is being added and the An item is being updated check boxes. Click Finish
Step 5: Add following constant variables to the event
receiver file.
private const string OpenPositionsListTitle = "Open Positions";
private const string TitleProperty = "Title";
private const string LoginName = @"SHAREPOINT\SYSTEM";
private const string JobDefinitionsListTitle = "Job Definitions";
private const string SubSiteName = "JobDefinitions";
private const string ErrorMessage = "The job you have entered is not defined in the Job Definitions List";
Step 6: Add a new method called checkItem to the event
receiver file.
Private bool checkItem(SPItemEventProperties properties)
{
string jobTitle = properties.AfterProperties[EventReceiver1.TitleProperty].ToString();
bool allowed = false;
SPWeb jobDefWeb = null;
SPList jobDefList;
SPUser privilegedAccount = properties.Web.AllUsers[EventReceiver1.LoginName];
SPUserToken privilegedToken = privilegedAccount.UserToken;
try
{
using (SPSite elevatedSite = new SPSite(properties.Web.Url, privilegedToken))
{
using (SPWeb elevatedWeb = elevatedSite.OpenWeb())
{
jobDefWeb = elevatedWeb.Webs[EventReceiver1.SubSiteName];
jobDefList = jobDefWeb.Lists[EventReceiver1.JobDefinitionsListTitle];
foreach (SPListItem item in jobDefList.Items)
{
if (item[EventReceiver1.TitleProperty].ToString() == jobTitle)
{
allowed = true;
break;
}
}
}
}
return (allowed);
}
finally
{
jobDefWeb.Dispose();
}
}
Step 7: Replace the ItemAdding method with the
following code.
public override void ItemAdding(SPItemEventProperties properties)
{
try
{
bool allowed = true;
if (properties.ListTitle == EventReceiver1.OpenPositionsListTitle)
{
allowed = checkItem(properties);
}
if (!allowed)
{
properties.Status = SPEventReceiverStatus.CancelWithError;
properties.ErrorMessage = EventReceiver1.ErrorMessage;
properties.Cancel = true;
}
}
catch (Exception ex)
{
properties.Status = SPEventReceiverStatus.CancelWithError;
properties.ErrorMessage = ex.Message;
properties.Cancel = true;
}
}
Step 8: Replace the ItemUpdating method with the
following code.
public override void ItemUpdating(SPItemEventProperties properties)
{
bool allowed = true;
if (properties.ListTitle == EventReceiver1.OpenPositionsListTitle)
{
allowed = checkItem(properties);
}
try
{
if (!allowed)
{
properties.Status = SPEventReceiverStatus.CancelWithError;
properties.ErrorMessage = EventReceiver1.ErrorMessage;
properties.Cancel = true;
}
}
catch (Exception ex)
{
properties.Status = SPEventReceiverStatus.CancelWithError;
properties.ErrorMessage = ex.Message;
properties.Cancel = true;
}
}
Step 9: Deploy the project.
1. In Solution Explorer, right-click
the project.
2. Then click Deploy
Step 10: Test the site
1. In the SharePoint site, in the Open Positions list,
click Add new item
2. In the Title field, provide a title for a job
description that does not exist in the Job Definitions list in the secured sub site.
3. Click Save You receive a message from the event
receiver.
4. In the Title field, provide a title for a job
description that exists in the Job Definitions list in the secured sub site.
5. Click Save. The position is created.
Enhancement
Once
you done all the steps above mention this is work perfectly. But if you add
another custom List to the same site, if you add a new item to that list, above
event receiver will execute but nothing will happen because of in the code we
check the list name before do anything.
But I want to make this event receiver execute only
for the Open Positions list.
To do this, you have to change few attributes in Elements.xml file
inside the event receiver.
Receivers element in the Elements.xml file look like this in your project
<Receivers ListTemplateId=“100“>
Do the changes to this element as follows to make your
event receiver to execute only when you do some changes to Open Positions list.
<Receivers ListUrl=“Lists/Open Positions“>
Hope this will help you......