Using Event Receivers in SharePoint Foundation 2010 (Part 1 of 2)

Summary:  Event receivers in Microsoft SharePoint Foundation 2010 enable your custom code to respond when specific actions occur on a SharePoint object. Practical examples in this article show you how to use events to enhance your SharePoint applications.

Applies to: Business Connectivity Services | Open XML | SharePoint Designer 2010 | SharePoint Foundation 2010 | SharePoint Online | SharePoint Server 2010 | Visual Studio

Provided by:  Ali Badereddin, Microsoft Corporation | Nick Gattuccio, Microsoft Corporation

Contents

  • Learning the Basics of Events in SharePoint Foundation 2010

  • Working with Events in SharePoint Foundation 2010

  • Using the Event Receiver Template in Visual Studio 2010

  • Additional Resources

Learning the Basics of Events in SharePoint Foundation 2010

An event receiver in Microsoft SharePoint Foundation 2010 is simply a method that is called when a triggering action occurs on a specified SharePoint object. Triggering events include actions such as adding, updating, deleting, moving, checking in, and checking out. SharePoint objects that listen for events—that is, event receiver hosts—include objects such as site collections, sites, lists, and workflows.

Events are valuable tools for SharePoint developers. When a user performs an action that affects a SharePoint site, you can trap that action and respond to it with custom code. For example, if a project manager needs to be alerted when new documents or files are added to a given document library, you could write event receiver code to send an e-mail notification to the project manager, and then bind that code to the item-addition action on the document library. SharePoint Foundation 2010 provides enormous flexibility for detecting and responding to SharePoint events.

Note

Microsoft Visual Studio 2010 now provides a SharePoint Event Receiver project template that automatically performs many of the tasks that are described in this article. To provide full descriptions of the actions that occur in the entire event pipeline, we do not use the Visual Studio 2010 Event Receiver project template. However, we do provide a brief summary of using Visual Studio 2010 to create event receivers, and we provide examples that use the template.

Events were first introduced in Windows SharePoint Services 2.0 but initially were supported only on document libraries. SharePoint events then were referred to as event sinks. In Windows SharePoint Services 3.0, the SharePoint events infrastructure took its current form, using managed event receivers.

Event receivers improved on event sinks in several ways. They are easier to use; they have more event types; and they are supported on lists, content types, workflows, and sites. In SharePoint Foundation 2010, new list and web events were introduced; additionally, site collections can now act as event hosts, After events can now be synchronous, and event cancellation and impersonation has improved.

How SharePoint Events Work: All You Need to Know in One Paragraph

A SharePoint event receiver is bound to a SharePoint object—the event host—and responds to a user action by triggering event receiver code. You compile your event receiver code into a managed assembly—that is, a .dll file that is deployed to the global assembly cache.

Where Can I Use Event Receivers?

If you want to add behaviors to the operations that happen in SharePoint, you can use event receivers to trigger your custom code whenever a certain operation takes place. Table 1 lists the various operations on which you can plug your custom code.

Table 1. Operations available to event receivers

Object

Operations

Site collection

  • Deletion

Web

  • Creation

  • URL modification

  • Deletion

List

  • Creation

  • Deletion

  • Received an e-mail message

Field

  • Creation

  • Update

  • Deletion

Item

  • Creation

  • Update

  • Deletion

  • Check in

  • Check out

  • File movement

  • File conversion

  • Adding attachment

  • Deleting attaching

Workflow

  • Start

  • Completed

  • Postponed

What Are Event Receivers?

An event receiver is a piece of managed code that responds to SharePoint events when specific triggering actions occur on a SharePoint object. Triggering actions include activities such as adding, updating, deleting, moving, checking in, and checking out.

To create an event receiver, you inherit from one of the event receiver base classes. SharePoint provides five event receiver base classes. (See Table 2 in the following section.) Note that each of the base classes supports only specified event hosts and events. You must select the correct event receiver base class for the host type you want to support.

After you write your event receivers in your event receiver class, you must compile the receiver into a managed assembly and then place it in the global assembly cache (GAC). Finally, you must bind the event receivers to a suitable event host. Later in this article, we discuss event binding and the different methods with which you can bind events.

What Are Event Hosts?

Event hosts are common SharePoint objects that expect to receive events—in other words, objects whose event receivers "listen" for SharePoint events. These SharePoint event host object types include instances of common objects such as SharePoint site collections, sites, and lists. Each event host type has a specific set of event receiver base types from which it can inherit.

Table 2 lists the event receiver base classes as well as the event host types that support each receiver, along with the events they support.

Table 2. Event receiver base classes and supported events

Event receiver base class

Available event host types

Supported events

SPWebEventReceiver

  • SPSite

  • SPWeb

  • SiteDeleting

  • SiteDeleted

  • WebAdding

  • WebProvisioned

  • WebDeleting

  • WebDeleted

  • WebMoving

  • WebMoved

SPListEventReceiver (lists)

  • SPSite

  • SPWeb

  • ListAdding

  • ListAdded

  • ListDeleting

  • ListDeleted

SPListEventReceiver (fields)

  • SPSite

  • SPWeb

  • SPList

  • SPContentType

  • FieldAdding

  • FieldAdded

  • FieldDeleting

  • FieldDeleted

  • FieldUpdating

  • FieldUpdated

SPItemEventReceiver

  • SPSite

  • SPWeb

  • SPList

  • SPContentType

  • ItemAdding

  • ItemAdded

  • ItemDeleting

  • ItemDeleted

  • ItemUpdating

  • ItemUpdated

  • ItemFileConverted

  • ItemFileMoving

  • ItemFileMoved

  • ItemCheckingIn

  • ItemCheckedIn

  • ItemCheckingOut

  • ItemCheckedOut

  • ItemAttachmentAdding

  • ItemAttachmentAdded

  • ItemAttachmentDeleting

  • ItemAttachmentDeleted

SPEmailEventReceiver

  • SPSite

  • SPWeb

  • SPList

  • EmailReceived

SPWorkflowEventReceiver

  • SPSite

  • SPWeb

  • SPList

  • SPContentType

  • WorkflowStarting

  • WorkflowStarted

  • WorkflowCompleted

  • WorkflowPostponed

Key Concepts in the SharePoint Event Model

In addition to the fundamental pieces of the event model—event receivers, event hosts, and the events themselves—the following are key concepts in the landscape of the SharePoint event model.

Before Events

A Before event occurs before the currently requested operation happens. For example, the ItemAdding event is a Before event that is raised before an item is added to a SharePoint list.

Looked at another way, Before events are raised when an action occurs before SharePoint writes to the content database. This provides an opportunity for an event receiver to perform tasks before data is committed to a database. A good example of the use of Before events is performing data validation, because Before events fire prior to commitment of data. You can also use Before (or synchronous) events to cancel user actions—for example, if data validation fails.

Event receiver code that is triggered by a Before event executes in the same thread as the code that is executing the user action that triggered it. For this reason, Before events are always synchronous. You can identify Before events because their member names end with the "-ing" suffix—ItemAdding, ListAdding, and so forth.

After Events

An After event is raised after the currently requested operation happens. For example, the ItemAdded event is an After event that is raised after an item has been added to a SharePoint list.

After events trigger event receivers that execute after user actions are committed to the content database; they invoke code that runs after the content database has been modified. This allows you to execute logic that occurs after a user has completed a specific action.

After events can execute either synchronously or asynchronously. If the After event is synchronous, it executes in the same thread in which the triggering action occurs. However, if the After event is asynchronous, it executes in a separate thread.

You can identify After events because their member names end with the "-ed" suffix—ItemDeleted, WebProvisioned, and so forth.

Synchronous Events

A synchronous event is executed in the same thread in which the triggering action is occurring. For example, when the user adds an item from the SharePoint user interface, the event is fully executed before returning to the user and showing that the item was added.

All Before events are synchronous events.

Asynchronous Events

An asynchronous event occurs at a later time than the action that triggered it, and it executes on a thread that is different from the one in which the triggering action is running. For example, when a user adds an item to a document library by using the SharePoint user interface, the event starts to execute before returning control to the user; however, there is no guarantee that the event receiver will finish executing before we show the user that the item has been added.

Event Binding

Event binding (also known as event registration) can be done by using the server object model or by using Feature XML. The following sections provide detailed information about binding events in SharePoint Foundation.

Event Cancellation

Event cancellation enables you to cancel an event receiver operation in a Before event prior to the conclusion of the action. For example, we can write some code in the ItemAdding event receiver that cancels the action of adding the item. So when the user tries to add an item, the operation is cancelled and the item is not added to the list. When the operation is cancelled, be sure to show the user an error message or provide a custom error message by redirecting the user to a specific URL.

Event Receiver Sequence

The event receiver sequence specifies the order in which an event receiver is executed in cases where an event triggers multiple event receivers. For example, if you have two ItemAdded event receivers bound to the same list (one from Assembly "1" and the other from Assembly "2"), the event receiver that is bound with a lower sequence number is executed first. A practical example is adding an event receiver to a system list that already has a system event receiver bound to it. In that case, you assign the new event receiver a higher sequence number.

The SharePoint Events Pipeline

Figure 1 illustrates how SharePoint events occur with respect to synchronization and sequencing.

Figure 1. SharePoint events pipeline

SharePoint events pipeline

Notice the following details:

  • Synchronous event receivers are called in sequential order based on the sequence number specified during event binding. This applies to both Before and After synchronous events.

  • Asynchronous After event receiver threads are initiated in sequential order based on the sequence number. However, there is no guarantee that they will finish in that same order.

  • An asynchronous After event can start at any time after its associated user action is performed. It may start before, at the same time as, or after the Web request is completed.

After a user initiates an action in the SharePoint user interface, and before SharePoint Foundation executes the user action, the synchronous Before events are raised. If there are multiple synchronous Before events, they are raised in the order specified by their sequence number. Similarly, synchronous After events are raised after SharePoint Foundation executes the user action. These, too, are raised in the order specified by sequence number. As you can see, all synchronous events are processed in the same thread as that in which the user action occurs.

Asynchronous After events, however, are processed on secondary threads.

Working with Events in SharePoint Foundation 2010

There are basically two steps in creating a SharePoint event. First, you identify the operation that you wish to associate with an event, inherit from the appropriate event receiver base class, and then write the custom code for your event receiver. Second, you bind your event to an appropriate SharePoint event host. (This step is also known as "registering" your event.)

After you write your event receiver code and compile it into a strongly signed assembly, you can use either of two ways to bind the event to its event host: You can use APIs in the SharePoint object model, or you can use Feature XML in a SharePoint solution. We discuss both methods in detail.

Using the Object Model vs. Using Solutions

In a nutshell, the difference between using the object model (OM) and using solutions to bind SharePoint events is this: The OM approach is more flexible and easier to develop, but it is difficult to deploy and maintain. The solutions approach is less flexible and more difficult to develop, but it is much easier to deploy and maintain.

When using the OM approach, you have the entire SharePoint object model at your disposal. You write your event receiver code, you compile it into an assembly that you deploy to the GAC, and you run code to bind the events in the assembly to a SharePoint event host.

This approach is useful when you are in development mode because it is easy to test and make changes to your event receiver code and the event binding, and then to rebuild and redeploy the project. However, when you move your code from a development platform to a production environment, this simplicity evaporates because you must deploy everything manually. This means that you must copy the event receiver code (that is, the managed assembly) to each individual front-end web server in the production environment. You then need to run the executable on one of the front-end web servers, and then run iisreset on each of the front-end web servers to refresh the cache on the IIS worker process (w3wp.exe). In a large production environment, this could be an extremely clumsy (and risky) undertaking.

The SharePoint solution approach differs in how it binds the event receiver definition. Furthermore, by having the event receiver code in the deployment (.wsp) package along with the solution files, deployment across a server farm is much easier and more reliable, and the event receiver definition becomes available by simply activating a Feature. Another important advantage of the solutions approach is that you can implement event receivers in partially trusted code (that is, in sandboxed solutions). Administrators at the site-collection level can then add event receivers. (Before SharePoint 2010, only farm administrators could add event receivers.)

Deployment, then, requires no more than steps that are normally used for SharePoint solution deployment by using a .wsp file. Running a single deployment command deploys the receiver assembly and event bindings to all of the front-end web servers after the Feature is activated.

Visual Studio 2010 makes this process even easier. Using Visual Studio provides the flexibility of the object model approach while preserving the economy of the solutions approach. In the following sections as we work with event receivers, we highlight ways in which Visual Studio 2010 has vastly simplified the process.

Using the Server Object Model

When using the server object model, you are concerned with three primary actions: creating event code, binding events, and modifying or changing event code. The following sections discuss each step in detail.

Note

Although we use Visual Studio in the following examples, we do not use the SharePoint project templates that are included with Visual Studio 2010. For this reason, you can use either Visual Studio 2008 or Visual Studio 2010 when recreating the following samples.

Creating Events by Using the Object Model

The first step in writing custom event receiver is overriding one of the event receiver base classes. The five SharePoint event receiver base classes are listed in Table 2 earlier in this article, but all of them inherit from the core event receiver base class, SPEventReceiverBase.

To create an event receiver

  1. In Visual Studio 2008 or Visual Studio 2010, create a C# class library project named, for example, MyReceiverAssembly.

    Important

    If you use Visual Studio 2010, be sure to target Microsoft .NET Framework 3.5. The reason is that SharePoint 2010 relies on .NET Framework 3.5. You can find this setting on the Application tab of the project properties, as shown in Figure 2.

    Figure 2. Targeting .NET Framework 3.5

    Targeting .NET Framework 3.5

  2. On the Build tab of the project properties, set Platform Target to either x64 or Any CPU, as shown in Figure 3. Do not select x86.

    Figure 3. Targeting the appropriate platform

    Targeting appropriate platform

  3. On the Signing tab of the project properties, select Sign the Assembly.

  4. Click Choose a strong name key file and then click New.

  5. In the Create Strong Key Name dialog box, in the Key file name text box, type any name. Clear the Protect my key file with a password check box, and then click OK.

  6. Rename your class; for example, MyReceiverClass.

  7. Add a reference to Microsoft.SharePoint.dll.

  8. In your class, create a reference to the Microsoft.SharePoint namespace by inserting the following statement:

    using Microsoft.SharePoint;

  9. Inherit from the appropriate subclass of SPEventReceiverBase, depending on the event you want to create. (Refer to Table 2.) For example, if you want to create and bind an ItemAdded event, inherit from the SPItemEventReceiver base class, as follows:

    Public class MyReceiverClass : SPItemEventReceiver

  10. Define the methods for the events you want to implement. A useful technique is to type public override and then press Spacebar. In Visual Studio, IntelliSense displays the available events on the class, as shown in Figure 4.

    Figure 4. Using IntelliSense to view available events

    Using IntelliSense to view available events

    If you selected the ItemAdded event, you now have the following method definition:

    Public override void ItemAdded(SPItemEventProperties properties)
    {
        base.ItemAdded(Properties;
    }
    
  11. Build the class library into a DLL.

  12. Place the DLL in the GAC by navigating to the %WINDIR%\assembly folder and then dragging your assembly into the folder.

    If you get an "Access Denied" error or another issue that prevents you from simply dropping the assembly to the cache, you can use the following procedure.

    1. Ensure that SharePoint development tools in Visual Studio 2010 are installed on your machine.

    2. Start the Visual Studio command prompt.

    3. Enter gacutil /i followed by the path to the assembly. If the operation is successful, you receive the message "Assembly successfully added to the cache."

    4. To confirm that your assembly was added, enter the following command in the command prompt to list all the assemblies that are in the specified directory in the assembly cache (in this case, in the cache directory named MyReceiverAssembly):

      gacutil /l MyReceiverAssembly

Binding Events by Using the Object Model

When you use the SharePoint Foundation object model, you can bind (register) any object that has the EventReceivers property. The EventReceivers property is of type SPEventReceiverDefinitionCollection, which facilitates adding event receiver definitions to event hosts. The following is a list of SharePoint objects that have this property and can serve as event hosts.

To bind an event receiver

  1. In Visual Studio 2008 or Visual Studio 2010, create a C# console application project named, for example, RegisterEvents.

    Important

    If you use Visual Studio 2010, be sure to target Microsoft .NET Framework 3.5. The reason is that SharePoint 2010 relies on .NET Framework 3.5. You can find this setting on the Application tab of the project properties, as shown earlier in Figure 2.

  2. Add a reference to Microsoft.SharePoint.dll.

  3. In your class, create a reference to the Microsoft.SharePoint namespace by inserting the following statement:

    using Microsoft.SharePoint;

  4. Add a new item of type SPEventReceiverDefinition to the EventReceivers collection on the specified object, similar to the following:

    SPEventReceiverDefinition def = list.EventReceivers.Add();

  5. To get the full name of the assembly that you created in the preceding procedure, go to the GAC, locate the assembly, right-click the assembly entry, and click Properties. The properties window should resemble Figure 5.

    Figure 5. Assembly properties in the GAC

    Assembly properties in GAC

  6. Copy the values from the properties window to specify the full name, version, culture, and public key token. In this example, the source code appears as follows:

    def.Assembly = "MyReceiverAssembly, Version=1.0.0.0, Culture=Neutral,PublicKeyToken=12e5e5525fb3d28a";

  7. Set the Class property. The Class property represents the fully qualified class name of the class that contains the event receiver, in the form namespace.class. In this example, the source code appears as follows:

    def.Class = "MyReceiverAssembly.MyReceiverClass";

  8. Set the Type property. In this example, the source code appears as follows:

    def.Type = SPEventReceiverType.ItemAdded;

  9. Set the Name property. This property is optional. You can provide a name for your event receiver definition, or you can ignore the value. In this example, the source code appears as follows:

    def.Name = "My ItemAdded Event Receiver";

  10. Set the Synchronization property. This property is optional. If you do not specify a value for this property, the property is set to Default (that is, SPEventReceiverSynchronization.Default). The default behavior is for Before events to be synchronous and After events to be asynchronous. In this example, the source code appears as follows:

    def.Synchronization = SPEventReceiverSynchronization.Synchronous;

  11. Set the SequenceNumber property. This property is optional. Use this property to set the order in which events fire when multiple events are in your event receiver definition. If you do not set this value, it defaults to 10000. When setting this value, you can select any value between 0 and (216)-1.

  12. Save the event receiver definition to the SharePoint content database by adding the following statement:

    def.Update();

Following is the full source code for the preceding procedure. When you run this code, your event is registered on the Tasks list of the https://localhost site. When you create a new item in the list, your ItemAdded event triggers.

using (SPSite site = new SPSite("https://localhost"))
{
    using (SPWeb web = site.OpenWeb())
    {
        SPList list = web.Lists["Tasks"];
        SPEventReceiverDefinition def = list.EventReceivers.Add();
        def.Assembly = 
          "MyReceiverAssembly, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=12e5e5525fb3d28a";
        def.Class = "MyReceiverAssembly.MyReceiverClass";
        def.Type = SPEventReceiverType.ItemAdded;
        def.Name = "My ItemAdded Event Receiver";
        def.Synchronization = SPEventReceiverSynchronization.Synchronous;
        def.SequenceNumber = 1000;
        def.Update();
    }
}

Changing Events

The SharePoint event model facilitates changing and redeploying your event receiver code. The following instructions illustrate how to make changes to the MyReceiverAssembly example project.

To update an event receiver

  1. In Visual Studio, open your project (such as the MyReceiverAssembly project) and make your changes.

  2. Rebuild the project to create a new build of the DLL file.

  3. Place the new build of the DLL in the GAC. Be sure to overwrite or delete the previous DLL.

  4. Run iisreset to clear the IIS cache and thus load the new version of the assembly in the GAC. This action ensures that SharePoint picks up your changes.

Using SharePoint Solutions

The alternative to using the SharePoint object model to create and deploy your event receivers is using SharePoint solutions. In this section, we step through the manual process of creating an event receiver solution.

You create events for implementation when using SharePoint solutions in the same way as when you use the SharePoint object model. Follow the procedure in the section Creating Events by Using the Object Model to create your events.

The real difference between these two ways of implementing events is in the binding, for which you use a SharePoint Feature deployed in a solution (.wsp) file.

Binding Events by Using Solutions

The following procedure creates a SharePoint Feature that takes the example event—the ItemAdded event, which we created in the MyReceiverAssembly DLL—and binds it to the Tasks list on the web site on which you want to activate the Feature.

To create a SharePoint Feature

  1. Create a folder with the same name as the Feature.

  2. In the new folder, create two XML files, named feature.xml and eventbinder.xml.

  3. Enable IntelliSense in the XML files by accessing the file properties and adding a reference to the target schema (.xsd) file, which is located in the …/TEMPLATE/XML/wss.xsd directory.

    Normally, you must recreate this link each time you open the XML file. However, if you are working in a Visual Studio project, all you need to do is to add the schema file to the project.

    But if you create a lot of CAML files in multiple Visual Studio projects, and if you do so frequently, this process might be cumbersome. An alternative method is to simply load the XSD file whenever a XML file is opened that references the schema. To accomplish this, do the following.

    1. Locate the XML file named Catalog.xml in the Visual Studio installation folder, which is commonly C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas.

    2. Reference the wss.xsd schema file from the Catalog.xml file by adding the following tag. Ensure that the href value is pointing to the correct location of the wss.xsd file.

      <Schema href="C:/Program Files/Common Files/Microsoft Shared/Web Server Extensions/12/TEMPLATE/XML/wss.xsd" targetNamespace="https://schemas.microsoft.com/sharepoint/" />

    Tip

    If you use Visual Studio 2010, you can effectively skip Step 3. When you open an XML file that contains the attribute xmlns="https://schemas.microsoft.com/sharepoint/", Visual Studio 2010 automatically adds a reference to wss.xsd and thus enables IntelliSense.

  4. In the feature.xml file, create a <Feature> element. Set the xmlns attribute to "https://schemas.microsoft.com/sharepoint/", set the Id attribute to a globally unique identifier (GUID), set the Scope attribute to "Web", and set the Title attribute to "EventBinderFeature".

    Important

    For the Id attribute, you must provide a valid GUID, which you can obtain within Visual Studio by running guidgen.exe.

  5. In the <Feature> element, add an <ElementManifests> element.

  6. In the <ElementManifests> element, add an <ElementManifest> element. Set the Location attribute to "eventbinder.xml".

  7. In the eventbinder.xml file, create an <Elements> element. Set the xmlns attribute to "https://schemas.microsoft.com/sharepoint/".

  8. In the <Elements> element, add a <Receivers> element. Set the ListUrl attribute to "Tasks".

  9. In the <Receivers> element, add a <Receiver> element.

  10. In the <Receiver> element, add the following elements, with an appropriate value for each:

    • <Assembly>

    • <Class>

    • <Type>

    • <Name>

    • <Synchronization>

    • <SequenceNumber>

After you complete the preceding procedure, the feature.xml file should resemble the following.

<Feature Id="E54C7FF5-1DF3-4B0B-8FFF-DB3185ECE8A6" 
         Scope="Web" 
         Title="Event Binder Feature"
         xmlns="https://schemas.microsoft.com/sharepoint/">
  <ElementManifests>
    <ElementManifest Location="eventbinder.xml" />
  </ElementManifests>
</Feature>

And the eventbinder.xml file should resemble the following.

<Elements xmlns="https://schemas.microsoft.com/sharepoint/">
  <Receivers ListUrl="Lists/Tasks">
    <Receiver>
      <Assembly>MyReceiverAssembly, Version=1.0.0.0, Culture=Neutral, 
        PublicKeyToken=12e5e5525fb3d28a</Assembly>
      <Class>MyReceiverAssembly.MyReceiverClass</Class>
      <Type>ItemAdded</Type>
      <Name>My ItemAdded Event Receiver</Name>
      <Synchronization>Synchronous</Synchronization>
      <SequenceNumber>1000</SequenceNumber>
    </Receiver>
  </Receivers>
</Elements>

Packaging the Solution

To deploy event receivers to your installation of SharePoint, you must assemble the files into a solution package (.wsp) file. The .wsp file is simply a cabinet (.cab) file whose file name extension is .wsp.

The solution manifest file tells SharePoint what to do with the files that are packaged in the .wsp file. For example, the <FeatureManifest> element specifies that this folder is a SharePoint Feature and thus it should be deployed to %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\FEATURES and be installed on the server farm. Likewise, the <Assembly> element specifies that this file is an assembly; its DeploymentTarget attribute indicates whether to deploy the assembly to the GAC or to a web application bin folder.

Prepare for, create, and edit the manifest.xml file as follows:

To prepare the solution contents

  1. Create a folder named "EventSolution".

  2. Copy the Feature folder EventBinder into the EventSolution folder.

  3. Copy the assembly MyReceiverAssembly.dll into the EventSolution folder.

  4. Create a XML file named "manifest.xml" in the EventSolution folder.

To edit the manifest.xml file

  1. In the manifest.xml file, create a <Solution> element. Set the xmlns attribute to "https://schemas.microsoft.com/sharepoint/", set the SolutionId attribute to a GUID, and set the Title attribute to "Event Receiver Solution".

  2. In the <Solution> element, add a <FeatureManifests> element.

  3. In the <FeatureManifests> element, add a <FeatureManifest> element. Set the Location attribute to "EventBinder\feature.xml".

  4. In the <Solution> element, add an <Assemblies> element.

  5. In the <Assemblies> element, add an <Assembly> element. Set the Location attribute to "MyReceiverAssembly", and set the DeploymentTarget attribute to "GlobalAssemblyCache".

The manifest.xml file should now resemble the following.

<Solution SolutionId="11C76135-CEEC-475B-9A93-67E5EF151B3C"
          Title="Event Receiver Solution"
          xmlns="https://schemas.microsoft.com/sharepoint/">
  <FeatureManifests>
    <FeatureManifest Location="EventBinder\feature.xml"/>
  </FeatureManifests>
  <Assemblies>
    <Assembly Location="MyReceiverAssembly" 
              DeploymentTarget="GlobalAssemblyCache">
    </Assembly>
  </Assemblies>
</Solution>

Now that the solution contents are ready, all that remains is to create the Diamond Directive File (DDF). A DDF contains information used by Microsoft Cabinet Maker (makecab.exe) to identify how to package and compress the files into a .cab file. (The DDF file itself is not placed into the .cab file.)

To create a DDF

  1. In the EvenSolution folder, create a file named "cab.dff" using a text editor, such as Notepad.

    Add the following information.

    ;
    .OPTION EXPLICIT
    .Set CabinetNameTemplate=MyEventSolution.wsp 
    .set DiskDirectoryTemplate=CDROM
    .Set CompressionType=MSZIP
    .Set UniqueFiles="ON"
    .Set Cabinet=on
    .Set DiskDirectory1=Package
    manifest.xml manifest.xml
    MyReceiverAssembly.dll MyReceiverAssembly.dll
    EventBinder\feature.xml EventBinder\feature.xml
    EventBinder\EventBinder.xml EventBinder\EventBinder.xml
    
  2. Save the file.

Important

In a DDF, ensure that the first line begins with a semicolon.

The OPTION EXPLICIT directive forces explicit declaration of all variables in the file. Setting UniqueFiles to "ON" ensures that destination files are unique. "ON" is the default value, because using the same file name twice usually means that the same file was accidentally included twice, which wastes disk space.

The last four lines in this DDF are the file mappings: The first name in each line is the source; the second name is the destination.

To create the solution package file, open a command prompt, navigate to the EventSolution folder, and enter the following command:

makecab /F cab.ddf

Cabinet Maker creates the .wsp file in a subfolder of the EventSolution folder named "Package". The name of the new file is MyEventSolution.wsp.

Deploying the Solution

SharePoint 2010 provides two kinds of solutions: farm solutions and sandboxed solutions. Sandboxed solutions are important because they allow the administrator of a site collection to upload and activate solutions at the site-collection scope. With sandboxed solutions, it is no longer necessary to have machine access to the WFE files.

By definition, however, using sandboxed solutions limits what code can be run. For example, if code in our event receiver tries to access the disk, the code runs without problems when the solution is deployed as a farm solution. But if the event receiver is deployed as a sandboxed solution, it throws a run-time exception when attempting to access the disk.

Note

In SharePoint 2010, Windows PowerShell supersedes the Stsadm.exe administration tool. You can still use Stsadm to deploy farm solutions, but we recommend using Windows PowerShell. You cannot use Stsadm to deploy sandboxed solutions.

To deploy a farm solution

  1. Upload the solution to the farm solution store by executing the following Windows PowerShell command:

    Add-SPSolution -LiteralPath full_path_to_solution

  2. Activate the solution by executing the following command:

    Install-SPSolution solution_name.wsp -GACDeployment

To deploy a sandboxed solution

  1. Upload the solution to the site-collection solution gallery by executing the following Windows PowerShell command:

    Add-SPUserSolution -LiteralPath full_path_to_solution -Site siteUrl

  2. Activate the solution by executing the following command:

    Install-SPUserSolution solution_name.wsp -Site siteUrl

When the solution is deployed, the Features are copied to the TEMPLATE\FEATURES folder, the managed assemblies are placed in the GAC, and other files are placed in their respective folders under TEMPLATES. You can now activate the Features.

If you need to retract a solution, use one of the following Windows PowerShell commands:

  • Farm solution: Uninstall-SPSolution solution_name.wsp

  • Sandboxed solution: Uninstall-SPUserSolution solution_name.wsp -Site siteUrl

After you retract a solution, you can delete it by using one of the following commands:

  • Farm solution: Remove-SPSolution solution_name.wsp

  • Sandboxed solution: Remove-SPUserSolution solution_name.wsp -Site siteUrl

Using the Event Receiver Template in Visual Studio 2010

Visual Studio 2010 provides an expanded set of SharePoint project templates in both Microsoft Visual Basic and C#, including one template for SharePoint event receivers. The project template simplifies handling events for SharePoint objects such as sites, lists, workflows, and other common items.

Note

This article does not focus on the Visual Studio project template for event receivers because it is intended to provide all the technical details that occur in the SharePoint event model, even those that are hidden by the Visual Studio project template. That said, this section shows you how easy it is to create a basic event receiver by using this project template.

When you create an event receiver project by using the Event Receiver project template in Visual Studio, several of the steps in this article are completed automatically. These steps include creating and signing the assembly, creating the Feature for event binding, solution packaging, deployment, and debugging.

To create a SharePoint event receiver by using the Visual Studio Event Receiver project template

  1. In Visual Studio 2010, create a new project by using the SharePoint 2010 Event Receiver template.

  2. Select the trust level for your SharePoint solution based on the implementation of your event receiver code. If the solution has no need for disk, network, or system-level access, sandboxed solution is the preferred choice because it is easier and more likely to be used.

  3. Select the events that you want to override. In our case, we want to override the ItemAdded event and bind it to the Tasks list.

    • What type of event receivers do you want? List Item Events

    • What item should be the event source? Tasks

    • Handle the following events: An item was added

  4. Click Finish.

  5. In the ItemAdded event, add your custom code.

  6. On the menu bar, click Build and then click Deploy Solution.

Your solution is packaged, added, and deployed! You can even set a breakpoint in your event receiver code and debug it.

To explore several practical examples of using the SharePoint event model, read the second part of this article: Using Event Receivers in SharePoint Foundation 2010 (Part 2 of 2).

Additional Resources

For more information, see the following resources: