Wednesday, December 30, 2015

Creating SharePoint Event Receivers in Visual Studio



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

No comments:

Post a Comment