Many developers have faced this issue, whenever we deal with the remote event receiver. I have faced this long back and after sometime, again I was creating an event receiver, with the App Only Permission, then I again met with the same exception. – Client Context will be NULL.
As part of investigating this again, I found some interesting facts like, through fiddler logs, it says that “401 error” while trying to obtain the SharePoint client context. But, I Use the ClientContext Object, then immediately it throws, that “Object Reference not set to an instance”.
So, there is a mystery behind the authentication and the Remote Event Receivers in SharePoint. Basically, there are two types of Permissions, we would have seen. Both has the advantages and limitations on its own.
1. User + App Only token.
2. App Only token.
A Check box decides this on the App Manifest.xml
On the XML File, it will looks like,
For Our Event Receivers to work with the AppOnly Permission, the default code snippet generated by the Visual Studio will not work.
public void ProcessOneWayEvent(SPRemoteEventProperties properties)
{
using (ClientContext clientContext = TokenHelper.CreateRemoteEventReceiverClientContext(properties))
{
if (clientContext != null)
{
clientContext.Load(clientContext.Web);
clientContext.ExecuteQuery();
}
}
}
Here on the above code, the ClientContext will always be null. Hence, we are not able to proceed. For this, there is a workaround. But eventually, the work around has is biggest draw back as well. But we can have a workaround for that also.
public void ProcessOneWayEvent(SPRemoteEventProperties properties)
{
string webUrl = properties.ItemEventProperties.WebUrl;
Uri webUri = new Uri(webUrl);
string realm = TokenHelper.GetRealmFromTargetUrl(webUri);
string accessToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, webUri.Authority, realm).AccessToken;
using (var clientContext = TokenHelper.GetClientContextWithAccessToken(webUrl, accessToken))
{
// DO YOUR ACTION HERE. A SAMPLE ACTION IS SHOWN BELOW.
clientContext.Load(clientContext.Web);
clientContext.ExecuteQuery();
string title = properties.ItemEventProperties.AfterProperties["Title"].ToString();
List lstDemoeventReceiver = clientContext.Web.Lists.GetByTitle(properties.ItemEventProperties.ListTitle);
ListItem itemDemoventReceiver = lstDemoeventReceiver.GetItemById(properties.ItemEventProperties.ListItemId);
itemDemoventReceiver["Column1"] = "Updated Value : " + title;
itemDemoventReceiver.Update();
clientContext.ExecuteQuery();
}
}
So, now the advantage is, with the AppOnly token, we are able to get the client context in the Remote Event Receiver.
In the same time, the disadvantage is, in the above piece of code, I am updating another column on the same list item. If you have a look on the screen, then the Modified By is coming as “SharePoint APP”. It should not be like that.
So, for this, we need to do a work around like, before updating the record, take the current user and then update that as well, wherever required. It is a simple work around, which we can easily do.
Happy Coding,
Sathish Nadarajan.
Leave a comment