Click here to Skip to main content
14,577,432 members

Adventures with SharePoint 2013 Remote Event Receivers – Part 1 of 3

Rate this:
4.67 (3 votes)
Please Sign up or sign in to vote.
4.67 (3 votes)
12 Aug 2013CPOL
Registering a remote event receiver to an App’s host web using the managed code (C#) client object model.

Introduction

Remote event receivers are a cool new feature of SharePoint 2013 and usually are quite straightforward to use. That is, until you try to register one programmatically…

One of my clients wanted to attach a remote event receiver to a list using an App. The list is hosted on the App’s host web. This series of posts will detail all the steps you need to take in order to achieve just that. As the documentation for SharePoint 2013 is a bit lacking (and in some cases completely wrong), I hope this documentation will save you all the head banging, tears and long office hours i had to put in, in order successfully get my remote event receiver to register and run on an App’s host web.

This series of posts will consist of the following parts:

  • Part 1 (this post) will deal with registering a remote event receiver to an App’s host web using the managed code (C#) client object model.
  • Part 2 will deal with working with RestSharp to perform calls to SharePoint’s REST services from a remote event receiver.
  • Part 3 will demonstrate an event receiver i get asked about a lot – how to create a post on a user/site’s newsfeed when a document is uploaded to a document library.

Set the stage

To get started, open Visual Studio 2012 (or the new Visual Studio 2013 preview) and create a new App for SharePoint 2013 project. Name the project however you like and set its type to SharePoint Hosted. Your popup should look similar to the following:

rer1

Now that we have an app ready, let’s add a remote event receiver: Right click on the project name and choose Add and New Item. Click on Remote Event Receiver and name it DocLibraryRER. Once you click on Finish the Choose Event Receiver Settings popup appears. These settings means nothing to us as we are planning on registering the remote event receiver to the host web, and these settings only affect the app web. Choose whatever settings you wish and click Finish. I used the following:

rer2

Pay attention to the Solution Explorer windows:

rer3

When we added the remote event receiver we set a chain of changes to our solution:

  • Our App project changed from SharePoint hosted to Auto-hosted.
  • A new web project was added to our solution in order to host the new remote event receiver.
  • The new remote event receiver (DocLibraryRER.svc) was created under the Services folder of the new web project.

Let’s recap what we done so far: We created a SharePoint hosted app and added a remote event receiver that will register itself to whatever event and list we chose in its settings.

In order register this new event receiver programmatically to a list on the host web site, we will have to handle the App Installed event. This event fires as soon as the App is installed by the admin, making it the perfect place to handle such registration tasks. There are three App life cycle events:

  • Installed – an event which fires just before the app is fully installed.
  • Uninstalling – an event which fires while the app is uninstalling
  • Upgraded – an event which fires just before the app is upgraded.

To handle any of these event highlight the App project name in the solution explorer and change the value of the life cycle event you wish to handle from False to True:

rer4

As we wish to handle the App Installed event, change its value from False to True as seen in the screenshot above.

As soon as we make the change, a new web service will get added to our web project. The new service is called AppEventReceiver.svc and it’s hosted under the Services folder. This service will handle all the App life cycle events, so even if you handle all three life cycle events, you will still use this one file.

Handling the App Installed Event

When handling App life events, we use the ProcessEvent public method as the entry point.

In order to make sure the code we write will only execute for the App Installed event, let’s add a check at the top of the ProcessEvent method for the type of event its currently handling. Change the ProcessEvent method as follows:

public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
{
    SPRemoteEventResult result = new SPRemoteEventResult();
    if (properties.EventType == SPRemoteEventType.AppInstalled)
    {
        using (ClientContext clientContext = TokenHelper.CreateAppEventClientContext(properties, false))
        {
            if (clientContext != null)
            {
                clientContext.Load(clientContext.Web);
                clientContext.ExecuteQuery();
            }
        }
    }
    return result;
}

Pay special attention to the CreateAppEventClientContext method call. The second parameter specifies whether we wish to target the App web (the web which the app runs at) or the host web (the host web of the App). As we are planning to attach the remote event receiver to a list on the host web, keep the second argument as false.

The list we are going to attach our remote event receiver to, is the Documents list which SharePoint creates by default for almost every site template. To load the list change the code inside the using call as follows:

using (ClientContext clientContext = TokenHelper.CreateAppEventClientContext(properties, false))
{
    if (clientContext != null)
    {
       var documentsList = clientContext.Web.Lists.GetByTitle("Documents");
       clientContext.Load(documentsList);
       clientContext.ExecuteQuery();
    }
}

In order to debug a remote event receiver you have to create a service bus within Azure and set your Visual Studio to use it. For a detailed tutorial on that subject check out Alexander Vanwynsberghe’s excellent post - Debugging SharePoint 2013 Remote Events Using The Windows Azure Service Bus.

If you take a look in the Elements.xml file that Visual Studio created for the remote event receiver we created earlier, you’ll notice the following element:

<Receiver>
      <Name>DocLibraryRERItemAdding</Name>
      <Type>ItemAdding</Type>
      <SequenceNumber>10000</SequenceNumber>
      <Url>~remoteAppUrl/Services/DocLibraryRER.svc</Url>
</Receiver>

If you look closely at the URL element you’ll notice that it uses a variable: ~remoteAppUrl. As the URLs of the remote event receiver differ between the debugging environment and production one, Visual Studio automatically replaces the variable with the correct URL as we build or package the App. Now you may think – ‘Cool, then let’s use it in our code as well!’ well…

3pfono

Sadly we can’t use this awesome variable when we programmatically attach the remote event receiver, as thus we are faced with the first Gotcha Moment: how can I find out the right URL for debugging (and later publishing) my remote event receiver?? Well, the answer is: ask the OperationContext object!

The OperationContext, as MSDN explains it, “Provides access to the execution context of a service method”. In our case, when we wish to debug, we will set the remote event receiver URL as follows:

// debugging url
string opContext = OperationContext.Current.Channel.LocalAddress.Uri.AbsoluteUri.Substring(
  0, OperationContext.Current.Channel.LocalAddress.Uri.AbsoluteUri.LastIndexOf("/"));

string remoteUrl = string.Format("{0}/DocLibraryRER.svc", opContext);

and for the deployment environment:

// deployment
string remoteUrl = string.Format("https://{0}/DocLibraryRER.svc", 
  OperationContext.Current.Channel.LocalAddress.Uri.DnsSafeHost + "/services");

For now, comment out the deployment URL as we are going to debug the remote event receiver to make sure it registers.

Next up we create the EventReceiverDefinitionCreationInformation object which contains all the information about the registered remote event receiver. The object defines (at minimum) the remote event receiver’s type, name, URL, and sequence number.

Our remote event receiver creation object will look as follows:

EventReceiverDefinitionCreationInformation newEventReceiver = new EventReceiverDefinitionCreationInformation()
{
    EventType = EventReceiverType.ItemAdding,
    ReceiverName = "DocLibraryRER",
    ReceiverUrl = remoteUrl,
    SequenceNumber = 1000 
};

The only thing left for us to do is attach the new remote event receiver to the list we defined earlier. Use the following snippet:

documentsList.EventReceivers.Add(newEventReceiver);
clientContext.ExecuteQuery();

We add the new EventReceiverDefinitionCreationInformation we created earlier to the EventReceivers collection of the list using the Add method. Since we are using the client object model we have to execute our commands to the server using the ExecuteQuery method of the client context object.

If you made it this far, add a breakpoint in the beginning of DocLibraryRER.svc.cs and hit the ol’ F5 key and check your new, shiny and pure awesome remote event receiver!

Well, that didn’t work, did it?

Setting the right permissions

39894415

This nifty little error brings us to the next Gotcha Moment: when working with Apps always remember to set its permissions. An App without permissions is like eating Oreos without milk – it simply wont work.

To set our App’s permissions, expend the App project in the solution explorer, and double click the AppManifest.xml file. The Manifest Designer will pop right up:

manifestdesigner

As you probably know by now, our App registers the remote event receiver to a list on the host web, thus, we need to ask the user’s permission to manage a specific list or web. For simplicity purposes we will use the web scope in this example.

Click on the Permissions tab. Under Scope choose Web and under Permissions choose Manage. Your permissions manager should look as follows:

permissions

Hit the ol’ F5 key again. This time a new popup will pop:

trust

This popup is directly related to the permissions we added in the Manifest Editor earlier. It asks the installing user for permissions to manage the current site. Click on Trust It and wait untill the App finishes installing. Once installed the App will run its default page file in your browser. Do not close this window! Closing it will detach the debug process.

Open another tab and head over to the site you installed the App to (if you need a refresher check out the App’s properties for the Site URL property). Open the Documents folder and try to upload a file. If everything went smooth, your breakpoint should be hit!

breakpoint

What's next?

Congratulations! You have successfully deployed an App which register a remote event receiver to a host web and managed to debug it. If you are going to deploy it to an App Catalog or even the Office Store don’t forget to change the remoteUrl variable to the deployment one.

If you wish to download the complete solution – click here.

In the next part of the series we will discuss how to work with RestSharp to call SharePoint 2013′s REST services from a remote event receiver.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

JTordgeman
Chief Technology Officer E4D Solutions
Israel Israel
Johnny Tordgeman is the CTO of the SharePoint division at E4D Solutions ltd, a boutique development and consulting firm in Israel. Johnny specializes in architecting enterprise level solutions built on top of Microsoft’s SharePoint platform and utilizing the latest in web technologies and methodologies such as jQuery, JavaScript, HTML5, CSS3, MVVM and SPA using Knockout.js.

Johnny is the author of “MCTS: Microsoft Silverlight 4 Development (70-506) Certification Guide” published by Packt Publishing, and is currently working on a hands-on SharePoint 2013 and HTML5 development course for E4D Learning.

Johnny is a skilled lecturer and a Microsoft certifies trainer and can be found speaking at conferences such as SharePoint Extreme, open houses on SharePoint and client side development and various user groups.

You can always find Johnny at http://blog.johnnyt.me, on twitter at @JTordgeman and on Linkedin.

Comments and Discussions

 
QuestionAwesome post; unfortunately no luck getting it to work Pin
David Cater10-Jan-14 7:08
MemberDavid Cater10-Jan-14 7:08 
GeneralCode Solution link is not working. Pin
vadivelub15-Dec-13 17:51
Membervadivelub15-Dec-13 17:51 
QuestionError while deploying Pin
Member 797038329-Oct-13 16:38
MemberMember 797038329-Oct-13 16:38 
QuestionGood article Pin
Anuruddi24-Oct-13 0:15
MemberAnuruddi24-Oct-13 0:15 
QuestionUnable to deploy Pin
Member 103141073-Oct-13 10:59
MemberMember 103141073-Oct-13 10:59 
AnswerRe: Unable to deploy Pin
JTordgeman3-Oct-13 19:24
MemberJTordgeman3-Oct-13 19:24 
GeneralRe: Unable to deploy Pin
Member 103141074-Oct-13 0:52
MemberMember 103141074-Oct-13 0:52 
GeneralRe: Unable to deploy Pin
JTordgeman4-Oct-13 9:12
MemberJTordgeman4-Oct-13 9:12 
GeneralRe: Unable to deploy Pin
Member 103141075-Oct-13 5:29
MemberMember 103141075-Oct-13 5:29 
GeneralRe: Unable to deploy Pin
JTordgeman5-Oct-13 6:00
MemberJTordgeman5-Oct-13 6:00 
GeneralRe: Unable to deploy Pin
Member 103141075-Oct-13 7:25
MemberMember 103141075-Oct-13 7:25 
GeneralRe: Unable to deploy Pin
JTordgeman7-Oct-13 6:32
MemberJTordgeman7-Oct-13 6:32 
GeneralRe: Unable to deploy Pin
Doug Haining8-Oct-13 6:15
MemberDoug Haining8-Oct-13 6:15 
GeneralRe: Unable to deploy Pin
JTordgeman8-Oct-13 7:24
MemberJTordgeman8-Oct-13 7:24 
QuestionService End Points Pin
Member 1023837428-Aug-13 7:42
MemberMember 1023837428-Aug-13 7:42 
AnswerRe: Service End Points Pin
JTordgeman9-Sep-13 17:54
MemberJTordgeman9-Sep-13 17:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Technical Blog
Posted 12 Aug 2013

Tagged as

Stats

55.6K views
3 bookmarked