Remote Event Receivers (RER) in SharePoint Online

Just like event receivers in the classic model, Remote Event Receivers (RER) in SharePoint Online also have before events and after events. Also called as synchronous and asynchronous events.

If you are not aware of this, what this essentially means is synchronous events are the -ing events. For example ItemAdding event where we can do a validation and cancel the event if the validation did not pass.

In the classic model, we create a class and deploy to the SharePoint farm. This will include the assembly in the w3 worker process. So, when an event occurs, it calls the method in the assembly. So, before events are very efficient and we can rely on it to perform these kinds of actions and we can do any complex or time consuming operation as well.

In the case of remote event receivers, our event receiver code is in a remote location. If we use before events using remote event handlers, a web service call is made to the remote location. Also, remote before events wait for a response back from the remote method to proceed (either commit or cancel).

The before events are modeled as two way events. This is because SharePoint calls into the web service to notify that an event is happening (such as adding or updating). Then after we process the event we could send back a cancel message. SharePoint will wait for a response to decide whether to cancel or continue. So, this is a blocking event for the user.

We need to be aware of the performance implication of this as it involves network traffic. Also, this is not guaranteed to be executed like the workflow which uses service bus architecture. The end user experience is not so good if there is a lot of delay in execution. So, we need to ensure this is a light weight operation we are trying to do.

This is not the case with after events where it is guaranteed to be executed. Because, this uses the WCF service one way method. Where it just notifies the remote web of the event. It doesn’t block the SharePoint processes.

Note that, remote event receivers are not supported by default in SharePoint hosted app since they cannot provide the remote endpoint. This is because they are restricted to only use JavaScript. There may be some workaround for this. I’ll probably do another post when I find one. Let me know if you found an approach.

It is easier to attach remote event receivers to artifacts in app web. This is because visual studio supports this natively. Today, lets explore the remote event receivers attached to a list in the app web.

Remote event receivers in app web

Lets create provider hosted app . In the app web project add a list instance based on Contacts list definition.

Now, if you right click on the Contacts list instance, you can add a Remote Event Receiver

You can choose which events you want to handle. We can also select multiple events

You can even add List events such as field added, or list deleted etc. You need to change the type of event receiver in the first drop down.

Once you click on Finish, visual studio will create and wire up the required web service end points. Notice that the remote endpoint is added to the remote web project. The list elements.xml will have the receiver information.

Based on the options selected, it will add two methods one is ProcessEvent which is a before event and the other is ProcessOneWayEvent which is an after event.

You can use the CSOM to make any changes in the event handler such as:

public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
{
SPRemoteEventResult result = new SPRemoteEventResult();
if(properties.EventType == SPRemoteEventType.ItemAdding)
{
string firstName = Convert.ToString(properties.ItemEventProperties.AfterProperties["FirstName"]).ToLower();
if (firstName.Contains("prashanth"))
{
result.Status = SPRemoteEventServiceStatus.CancelWithError;
result.ErrorMessage = "My name already exists!";
}

result.ChangedItemProperties.Add("FirstName", firstName.ToUpper());
}
using (ClientContext clientContext = TokenHelper.CreateRemoteEventReceiverClientContext(properties))
{
if (clientContext != null)
{
clientContext.Load(clientContext.Web);
//do something
clientContext.ExecuteQuery();
}
}

return result;
}

and after event such as (here I am using SP as an alias for Microsoft.SharePoint.Client namespace.

public void ProcessOneWayEvent(SPRemoteEventProperties properties)
{
if (properties.EventType == SPRemoteEventType.ItemAdded)
{
string firstName = Convert.ToString(properties.ItemEventProperties.AfterProperties["FirstName"]);
int listItemId = properties.ItemEventProperties.ListItemId;
Guid listId = properties.ItemEventProperties.ListId;
using (ClientContext clientContext = TokenHelper.CreateRemoteEventReceiverClientContext(properties))
{
if (clientContext != null)
{
Web web = clientContext.Web;
SP.List list = web.Lists.GetById(listId);
SP.ListItem item = list.GetItemById(listItemId);

item["FirstNamePhonetic"] = firstName + " Phonetic";
item.Update();
clientContext.ExecuteQuery();
}
}
}

When we try to debug the project, we’ll get a message that we cannot debug the remote event handler.

To enable debugging, we can open the windows powershell window. Ensure that you have installed and configured the azure powershell. Run the command Add-AzureAccount. This will prompt with an azure login window.

Login to the azure account

Run the command
[ps]
New-AzureSBNamespace -Name <uniquenamespace>
[/ps]

You need to choose a uniquenamespace which is unique across the web which no one else has chosen.

Copy the generated connection string

Go to the properties of the app web project in visual studio. Click on the SharePoint tab. Scroll down to select the option ‘Enable debugging via Microsoft Azure service bus’. Paste the connection string generated from above command.

Now, you should be able to set breakpoints in the event receiver and debug.

I have uploaded the source code to github at ProviderHostedAppRER

Leave a Reply

Your email address will not be published. Required fields are marked *