It should come as no surprise that Microsoft’s strategy for SharePoint 2013 is cloud-based, SaaS, Hosted Services or whatever you want to call it.  Whatever the name, the outcome is that custom, server-side code is no longer the way to go in the SharePoint world.  This brings into question the fate of one of the workhorses of SharePoint since 2003: the Event Receiver.  Microsoft has done a great job of exposing web services and creating the Client Side Object Model to enable scripting, but that doesn’t work when your application needs to react to an event that occurs in SharePoint.

SharePoint workflow could provide some of that functionality, but there is an overhead cost to workflow.  When architecting a SharePoint-based solution and the question “Workflow or Event Receiver?” comes up, I always prefer event receivers until it’s proven that the process needs a workflow.  If all the process needs to do is fire off an e-mail or update a field in another list or database, then why incur the overhead of a workflow when an event receiver will do the job with minimal management and overhead?  But that doesn’t work in an app for SharePoint or in a hosted environment that doesn’t allow custom code…or does it?

I’m guessing you can tell from the title of this post what the answer to that is — yes, with remote event receivers.

A remote event receiver is a web service which is called when an event occurs in SharePoint.  In theory, the web service can be any service that conforms to the service contract IRemoteEventService.  Visual Studio, with the Office apps tools installed, contains a template that includes an App Web and stubbed out code for a remote event handler, and that is what this post will concentrate on. In Visual Studio 2012, you just have to create a new SharePoint app and then add a remote event receiver to get the stubbed-out code.  When you add an event receiver, Visual Studio will add an app web if one does not already exist for the project.  The app web is intended as a location for all the remote services you may need for your app, but in this case will contain just the remote event receiver

Remote event receivers can be written for List Events, List Item Events and Web events and some new App events, but not for List EMail Events or List Workflow Events.  They support all of the events for each category above except the List’s “List Received a Context Event” event.

When you add a Remote Event Receiver to a SharePoint app, it creates the manifest and elements.xml for you, but let’s peel back the cover and look at the elements.xml.

<Receivers ListTemplateId=100>
     <Receiver>
         <Name>RemoteEventReceiver1ItemAdding</Name>
         <Type>ItemAdding</Type>
         <SequenceNumber>10000</SequenceNumber
         <Url>~remoteAppUrl/RemoteEventReceiver1.svc<Url>
     </Receiver>

     <Receiver>
         <Name>RemoteEventReceiver1ItemAdded</Name>
         <Type>ItemAdding</Type>
         <SequenceNumber>10000</SequenceNumber>
         <Url>~remoteAppUrl/RemoteEventReceiver1.svc<Url>
     </Receiver>
</Receivers>

As you can see above, the specification for the receiver looks pretty similar to previous versions of SharePoint, but instead of seeing Assembly and Class elements, we see a URL.  In this case, the URL is represented by the token ~remoteAppUrl because this is specified as an autohosted app rather than a provider hosted app.  If you’re not familiar, auto-hosted apps use Azure to automatically provision and host services and it’s worth looking into auto-hosted vs. provider hosted apps.  If this were a provider-hosted app, the URL would contain the absolute URL of the service.

The above is all that gets deployed to SharePoint when your app is installed — so far there is no actual code, simply a declaration of the location of you service.  So now let’s look at the other end of the equation: the service that will act as the event receiver.  The structure of remote event receivers is different than server-side event receivers.  Rather than overriding each method, you only have two methods, ProcessEvent() and ProcessOneWayEvent().  These handle all the -ing (synchronous) and -ed (asynchronous) methods for each event type respectively.  So rather than having a method for each event, ProcessEvent() is called for all of the -ing type events and ProcessOneWayEvent() is called for all of the -ed type of events which you have specified in your feature definition above.  That means you write your code for all of the events in one of these two methods. You simply have to determine which event your method is being called for by examining the SPRemoteEventProperties.EventType enumeration passed in when Sharepoint calls the receiver.

ProcessEvent (the -ing handler) returns an SPRemoteEventResult which includes a status and (optional) error message.  Just like the server-side version, this allows you to cancel an event and display a message.  For Item events it inlcudes dictionaries for the before and after properties, list information, user information and everything you would expect in an event receiver.

In all, Microsoft has done a great job keeping one of the most useful features of SharePoint useful in a hosted environment.  Remote event receivers do almost everything the server-side version does.  The only drawback is the lack of support for the ListEMail operation and to a lesser extent the Workflow options.  I’ve never seen a use for the latter because workflow can do most of what is listed there.  The former I have used in the past for a couple of different scenarios, including receiving faxes and scans, so those scenarios will require a different approach.  However, it is reassuring to know that even in a hosted scenario, event receivers remain extremely powerful tool in your SharePoint workbelt.

There is much more detail to remote event receivers and you will be hearing more about them later.  This post glosses over some of the points (like OAuth for a SharePoint app and reaching back into SharePoint from your web service to get information and context)  but hopefully it has provided an overview of what to look for in SharePoint 2013.