Export (0) Print
Expand All

How to: Create an event receiver for an app for SharePoint

apps for SharePoint

Learn how to handle events in a provider-hosted app for SharePoint by using Visual Studio.

Last modified: April 29, 2014

Applies to: apps for SharePoint | Office 365 | SharePoint Server 2013

The Perform basic data access operations by using CSOM in apps sample shows how you can programmatically manipulate lists and list items in apps for SharePoint. The example in this topic shows how you can extend that sample’s functionality by using a remote event receiver to handle remote events that occur in lists and list items. This topic also shows how you can handle events that occur to the app for SharePoint itself by using an app event receiver. The logic for remote event receivers and app event receivers is contained in code files that are located in web services in the project for the host web application.

  • A local installation of Visual Studio 2013.

  • A local installation of Office Developer Tools for Visual Studio 2013.

  • A local installation of Web Deploy, which you can download from Web Deploy.

  • A local installation of Microsoft SharePoint 2013. In addition, the installation must be configured to use OAuth if you want to run an event receiver, for example, to test and debug it.

    Note Note

    SharePoint 2013 is already configured to use OAuth if you’re testing the app on a target website that was created from the Developer Site site definition. (You can create such a website in SharePoint 2013 Central Administration.)

  • A local copy of the Perform basic data access operations by using CSOM in apps sample.

Core concepts

Before you start these procedures, you should have a basic understanding of what apps for SharePoint are and how apps for SharePoint that are provider-hosted and SharePoint-hosted differ. You should also understand the fundamental concepts of how to handle events in apps for SharePoint. The topics in Table 1 should give you that understanding.

Table 1. Core concepts for handling events in a provider-hosted app

Article title

Description

Apps for SharePoint overview

Learn about how you can use the new app model in SharePoint 2013 to create apps, which are small, easy-to-use solutions for end users.

Important aspects of the app for SharePoint architecture and development landscape

Learn about the model for apps for SharePoint and aspects of its architecture, including the app hosting options, the user interface options, the deployment system, the security system, and the lifecycle.

Choose patterns for developing and hosting your app for SharePoint

Learn more details about the different ways that you can host apps for SharePoint.

Handling events in apps for SharePoint

Learn about the different types of events that you can handle in an app for SharePoint and how to implement them.

This sample demonstrates how to create and manage lists and list items in an app for SharePoint by using CSOM code. In the procedures of this section, you extend an app for SharePoint by adding a remote event receiver and enabling it to handle events that occur to list items in the app.

To follow along with this article and enter the code yourself, download the sample from Perform basic data access operations by using CSOM in apps, and then open the sample in Visual Studio. If you would rather view a completed version of the code, download the sample for Use event receivers to handle events in apps for SharePoint. This sample is the same as the previous sample except that the remote event receiver and the app event receiver have already been added and configured.

To add a remote event receiver

  1. In Visual Studio, open Solution Explorer, and then choose the app project's node.

  2. On the menu bar, choose Project, Add New Item.

  3. In the Installed Templates pane, choose the Office/ SharePoint node.

  4. In the Templates pane, choose the Remote Event Receiver template.

  5. In the Name box, leave the default name (RemoteEventReceiver1), and then choose the Add button.

  6. In the What type of event receiver do you want? list, choose List Item Events.

    This example shows how to handle list item events. If you want to handle list events or web events, choose that type of receiver instead.

  7. In the What item should be the event source? list, choose Custom List.

    This example uses custom generic lists for its list data. This type of receiver can also handle events that occur in standard SharePoint lists, such as Announcements or Contacts.

  8. In the Handle the following events list, choose An item is being added, and then choose the Finish button.

    A web service is added to the web application to handle the remote event that you specified. A remote event receiver is added to the app for SharePoint and references the web service and the two list item events in the receiver’s Elements.xml file.

  9. Perform the following steps to add a non-customizable list based on an existing list type of Custom List to the app for SharePoint. You'll insert items into that list later when you run the code.

  10. In Visual Studio, open Solution Explorer, and then choose the app project's node.

  11. On the menu bar, choose Project, Add New Item.

  12. In the Installed Templates pane, choose the Office SharePoint node.

  13. In the Templates pane, choose the List template.

  14. In the Name box, leave the default name (List1), and then choose the Add button.

  15. Choose the Create a non-customizable list based on an existing list type of option button, choose Custom List in the list, and then choose the Finish button.

To add functionality to the remote event receiver

  1. In the code file for the service of the remote event receiver (that is, RemoteEventReceiver1.svc.cs), add the following code.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Text;
    using Microsoft.SharePoint.Client;
    using Microsoft.SharePoint.Client.EventReceivers;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    
    
    namespace BasicDataOperationsWeb
    {
        public class RemoteEventReceiver1 : IRemoteEventService
        {
            public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
            {
                // When a "before" event occurs (such as ItemAdding), call the event receiver code.
                ListRemoteEventReceiver(properties);
                return new SPRemoteEventResult();
            }
    
            public void ProcessOneWayEvent(SPRemoteEventProperties properties)
            {
                // When an "after" event occurs (such as ItemAdded), call the event receiver code.            
            }
    
            public static void ListRemoteEventReceiver(SPRemoteEventProperties properties)
            {
                // This code works only if OAuth on the server that's running SharePoint is set up with an ACS token.
                // Code that works with S2S setup is similar, but some changes are required.
                string logListTitle = "EventLog";
    
                // Return if the event is from the EventLog list. Otherwise, it may go into an infinite loop.
                if (string.Equals(properties.ItemEventProperties.ListTitle, logListTitle, StringComparison.OrdinalIgnoreCase))
                    return;
    
                // Get the token from the request header.
                HttpRequestMessageProperty requestProperty = (HttpRequestMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name];
                string contextTokenString = requestProperty.Headers["X-SP-ContextToken"];
    
                // If there is a valid token, continue.
                if (contextTokenString != null)
                {
                    SharePointContextToken contextToken =
                        TokenHelper.ReadAndValidateContextToken(contextTokenString, requestProperty.Headers[HttpRequestHeader.Host]);
    
                    Uri sharepointUrl = new Uri(properties.ItemEventProperties.WebUrl);
                    string accessToken = TokenHelper.GetAccessToken(contextToken, sharepointUrl.Authority).AccessToken;
                    bool exists = false;
    
                    // Retrieve the log list "EventLog" and add the name of the event that occurred to it with a date/time stamp.
                    using (ClientContext clientContext = TokenHelper.GetClientContextWithAccessToken(sharepointUrl.ToString(), accessToken))
                    {
                        clientContext.Load(clientContext.Web);
                        clientContext.ExecuteQuery();
                        List logList = clientContext.Web.Lists.GetByTitle(logListTitle);
    
                        try
                        {
                            clientContext.Load(logList);
                            clientContext.ExecuteQuery();
                            exists = true;
                        }
    
                        catch (Microsoft.SharePoint.Client.ServerUnauthorizedAccessException)
                        {
                            // If the user doesn't have permissions to access the server that's running SharePoint, return.
                            return;
                        }
    
                        catch (Microsoft.SharePoint.Client.ServerException)
                        {
                            // If an error occurs on the server that's running SharePoint, return.
                            exists = false;
                        }
    
                        // Create a log list called "EventLog" if it doesn't already exist.
                        if (!exists)
                        {
                            ListCreationInformation listInfo = new ListCreationInformation();
                            listInfo.Title = logListTitle;
                            // Create a generic custom list.
                            listInfo.TemplateType = 100;
                            clientContext.Web.Lists.Add(listInfo);
                            clientContext.Web.Context.ExecuteQuery();
                        }
    
                        // Add the event entry to the EventLog list.
                        string itemTitle = "Event: " + properties.EventType.ToString() + " occurred on: " + DateTime.Now.ToString(" yyyy/MM/dd/HH:mm:ss:fffffff");
                        ListCollection lists = clientContext.Web.Lists;
                        List selectedList = lists.GetByTitle(logListTitle);
                        clientContext.Load<ListCollection>(lists);
                        clientContext.Load<List>(selectedList);
                        ListItemCreationInformation listItemCreationInfo = new ListItemCreationInformation();
                        var listItem = selectedList.AddItem(listItemCreationInfo);
                        listItem["Title"] = itemTitle;
                        listItem.Update();
                        clientContext.ExecuteQuery();
                    }
                }
            }
    
        }
    }
    

    This code performs the following tasks.

    • Verifies whether a valid token for the remote app for SharePoint exists, and if so, whether the token is valid in this context.

    • If a list that's named EventLog doesn’t already exist, creates one to contain the names of the remote events that occur.

    • Adds an entry to the list for the event, including a time and date stamp.

  2. In Home.aspx.cs, change all instances of SPHostUrl to SPAppWebUrl.

    For example, sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]); should be changed to sharepointUrl = new Uri(Request.QueryString["SPAppWebUrl"]);. Remote event receivers for an app for SharePoint work only on the app web; they don’t work on the host web. For more information, see Host webs, app webs, and SharePoint components in SharePoint 2013.

  3. In the Web.config file, change the ClientID value to the ID value of your app website.

    This step ensures that the app web, not the host web, is used for accessing the lists and list items.

  4. Make sure that the Site Url property of the app for SharePoint project is set to the URL of the local system.

    Important note Important

    To debug an app for SharePoint that has remote event receivers and app event receivers, you must open it on a computer that has local installations of Visual Studio and SharePoint. However, the event receivers for such an app will work on remote deployments after you deploy it.

Now that the app for SharePoint has a remote event receiver to handle list item events, add an app event receiver that triggers when the app is installed.

To add an app event receiver

  1. In Solution Explorer, choose the node for the app for SharePoint project.

  2. In the Properties window, set the Handle App Installed event to True.

    A web service that's named AppEventReceiver.svc is added to the web application. This service contains a code file to handle the app-related events.

  3. In that code file (AppEventReceiver.svc.cs), replace the existing code with the following code.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.Text;
    using Microsoft.SharePoint.Client;
    using Microsoft.SharePoint.Client.EventReceivers;
    
    namespace BasicDataOperationsWeb
    {
        public class AppEventReceiver : IRemoteEventService
        {
            public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
            {
                // When an app event occurs, log it.
                LogAppEvents(properties.EventType.ToString());
                return new SPRemoteEventResult();
            }
    
            public void ProcessOneWayEvent(SPRemoteEventProperties properties)
            {
                // This method is not used by app events.
            }
    
            public static void LogAppEvents(string eventType)
            {
                // Creates a log folder for app events, names the folder "SPAppEventLogs" in the 
                // \My Documents folder, and then creates a file that identifies the event and a 
                // date/time stamp when the app event occurred.
                // You must include an exception handler in the app event receiver, because 
                // unhandled exceptions can prevent the app from loading.
                try
                {
                    string folder = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                        "SPAppEventLog");
    
                    // Create the "SPAppEventLogs" folder if it doesn't already exist.
                    if (!System.IO.Directory.Exists(folder))
                        System.IO.Directory.CreateDirectory(folder);
    
                    // Name the log file using the date/time stamp when the app event receiver
                    // fired, such as "AppInstalled20121130030240329.log". Note that this is 
                    // only a simple procedure for illustrative purpose; you can replace this 
                    // with any code you like to respond to the event.
                    string path = string.Format("{0}\\{1}{2}.log", folder,
                        eventType, DateTime.Now.ToString("yyyyMMddhhmmssfff"));
    
                    // Create the log file.
                    using (System.IO.FileStream fs = System.IO.File.Create(path))
                    {
                        fs.Flush();
                        fs.Close();
                    }
                }
                catch (Exception)
                {
                }
    
                return;
            }
        }
    }
    

    When the app event occurs in this example (that is, the app is installed), the code performs the following tasks.

    • The code creates a folder in your \My Documents folder and names the new folder SPAppEventLong.

    • The code writes a file to that folder and names the file based on the name of the event and the date and time when it occurred.

    NoteNote

    The app event receiver creates external files rather items in a SharePoint list because the Handle App Installed event occurs before any SharePoint lists are available and the app for SharePoint hasn’t loaded yet.

After you create and configure the code and elements for the remote event receiver and the app event receiver, you can test their event handlers to ensure that they work correctly.

To run and test the event handlers

  1. Choose the F5 key to run the project.

    The app for SharePoint site opens.

  2. When prompted, enter your credentials on the server.

  3. In the list of apps, choose your app to run it.

    Your app for SharePoint runs, and a table of available lists appears and includes List1.

  4. Choose the ID of List1.

    That ID is copied to the Retrieve List Items box.

  5. Choose the Retrieve List Items button.

    List1 appears with no items in it.

  6. In the Add Item box, specify First Item, and then choose the Add Item button.

    A list item that's named First Item is added to List1, which causes the remote event receiver to fire and add an entry to the EventLog list.

  7. Choose the Refresh Lists button to return to the table of lists.

    In the table, a new list that's named EventLog appears.

  8. Choose the ListID GUID value for EventLog, and then choose the Retrieve List Items button.

    A table for EventLog appears with an entry for the Handle ItemAdding event that occurred when you added the item to List1.

  9. In File Explorer, view the content of the \My Documents folder.

    A new folder called SPAppEventLog appears. This folder contains a file for each app event that occurred.

  10. Open the SPAppEventLog folder.

    Because this example handles only one app event (Handle App Installed), the folder should contain only one file, which has a name that's similar to AppInstalled20120530083328271.log. The exact name depends on the time/date stamp.

This article demonstrated how to add a simple remote event receiver and an app event receiver to an app for SharePoint. As a next step, consider the following tasks:

Show:
© 2014 Microsoft