Remote Event Receivers
Event receivers in earlier versions of
SharePoint primarily ran on the SharePoint Server to handle events that occurred
on SharePoint objects such as list, libraries, site etc.
In SharePoint 2013, a new concept, Remote Event Receivers, has been introduced, where the event generated by a SharePoint app could be listened to and handled by the SharePoint Server.
In other words, we could create SharePoint Apps (that is a standalone module of code that is complete in itself and can be installed / uninstalled independently on a Client) that can act as event generators. The handlers can be written using web services. These are very similar to the event receivers in the earlier version - except that these work in remote clients. This provides substantially more scope for including useful functionality in our SharePoint Apps.
In SharePoint 2013, a new concept, Remote Event Receivers, has been introduced, where the event generated by a SharePoint app could be listened to and handled by the SharePoint Server.
In other words, we could create SharePoint Apps (that is a standalone module of code that is complete in itself and can be installed / uninstalled independently on a Client) that can act as event generators. The handlers can be written using web services. These are very similar to the event receivers in the earlier version - except that these work in remote clients. This provides substantially more scope for including useful functionality in our SharePoint Apps.
Remote
event receivers are done by means of Web services, that listen for events to
occur. Instead of running code on the SP server, the app fires an event that is
handled by this web service. By registering a remote end-point we can invoke
either a one-way or two-way event receiver. Visual Studio 2013 provides
templates to create a Remote Event Receiver, that creates the skeleton for this
set up, that we can build on, to meet our requirements. By default, when we use
Visual Studio 2013 to create the remote event receiver, there are 2 methods in
the WCF service; they are:
1.
ProcessEvent() that handles events that occur before an action
occurs, such as when a user adds or deletes a list item. This is a synchronous
event (2-way that can handle "-ing" (current) events) that can
call-back to SharePoint, for example cancelling an addition to a list
2.
ProcessOneWayEvent() that handles events that occur after an
action occurs, such as after a user adds an item to a list or deletes an item
from a list. This is an asynchronous event (1-way that can handle
"-ed" (past) events, fire and forget type)
Remote event receivers handles events in an item in the app such
as list item, library item or web. In remote event receivers, app
responds, when ever item added, updated or deleted in a list/library. When ever
creating new remote event receiver you can select the type of event receiver.
for Eg. you select ListItemEvent, that fires whenever user add/updates/deletes
the list item.
How Remote Events Works?
Remote event receivers
follow the typical three patterns for authentication that are used for Auto
hosted and SharePoint-hosted Apps for SharePoint: on-premises only, in the
cloud only, and hybrid where part is on-premises and part is in the cloud.
Remote event receivers only need to be concerned about authentication if they
need to call back into SharePoint to perform some action on SharePoint. If your
remote event receiver is of the fire-and-forget model, or if you are simply
performing a validation and optionally cancelling an event, you do not need to
be concerned with authentication in your code, but the manifest does need to
have the correct designation. Figure 1 shows the on-premises-only and
cloud-only configurations as well as the appropriate authentication used by the
remote event receiver if your code needs to call back into SharePoint.
FIGURE 1:
Some enterprises that have
their SharePoint site on-premises will choose to be configured for a hybrid
environment where their remote event receivers may reside either on internal
servers or in the cloud. In this case the enterprise might want a single authentication
method and programming model for its remote event receivers that will work
equally well regardless of where the remote event receiver is hosted. To
accommodate this, the enterprise must follow the Microsoft-provided guidance to
configure SharePoint to use Windows Azure Access Control Services (ACS) as the
authorization service and expose the appropriate endpoints for SharePoint and
any internally hosted remote event receivers to the public Internet. ACS must
be able to access these endpoints to provide the needed authentication via
OAuth. Figure 2 shows this hybrid pattern.
FIGURE 2
Although you have the
opportunity to call back into SharePoint to do additional work within the app
web, host web, or elsewhere depending on your app’s permissions, sometimes you
might simply want to make some alterations on the list item and its properties
that are currently being processed in the ProcessEvent method. You
can do this by evaluating any value passed in on
the properties object and then use
the SPRemoteEventResult object and
its ChangedItemProperties object to pass your alterations back to
SharePoint.
For instance, you can use
the properties.ItemEventProperties.AfterProperties object in your
validation logic to assess whether the incoming values are as you expected them
to be. Once you make any changes to your result object this will be
passed back to SharePoint. SharePoint will update the list columns accordingly.
The
following Try It Out walks you through using
the SPRemoteEventResult object. Additionally, you will see in this
example that because your app does not explicitly need to call back into
SharePoint to read/write data, there is no need to use
the TokenHelper class in your code.
Below
are the The Code Base examples of two
methods:
ProcessEvent method:
which
handles the app installed/uninstalling event.
After
the app gets installed, it attaches the Remote Event Receiver with the Product
list. During the uninstalling event, it deletes the Remote Event Receiver from
the list
public class AppEventReceiver : IRemoteEventService
{
public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
{
SPRemoteEventResult result = new SPRemoteEventResult();
if (properties.EventType == SPRemoteEventType.AppInstalled)
{
using (ClientContext clientContext = TokenHelper.CreateAppEventClientContext(properties, false))
{
if (clientContext != null)
{
//Get reference to the host web list with name Products
var documentsList = clientContext.Web.Lists.GetByTitle(“Products”);
clientContext.Load(documentsList);
clientContext.ExecuteQuery();
string remoteUrl = “https://ur cloud host web url”;
{
public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
{
SPRemoteEventResult result = new SPRemoteEventResult();
if (properties.EventType == SPRemoteEventType.AppInstalled)
{
using (ClientContext clientContext = TokenHelper.CreateAppEventClientContext(properties, false))
{
if (clientContext != null)
{
//Get reference to the host web list with name Products
var documentsList = clientContext.Web.Lists.GetByTitle(“Products”);
clientContext.Load(documentsList);
clientContext.ExecuteQuery();
string remoteUrl = “https://ur cloud host web url”;
//Create the remote event receiver definition
EventReceiverDefinitionCreationInformation newEventReceiver =new EventReceiverDefinitionCreationInformation()
{
EventType = EventReceiverType.ItemAdded,
ReceiverAssembly = Assembly.GetExecutingAssembly().FullName,
ReceiverName = “ProductRemoteEventReceiver”,
ReceiverClass = “ProductRemoteEventReceiver”,
ReceiverUrl = remoteUrl,
SequenceNumber = 15000
};
EventReceiverDefinitionCreationInformation newEventReceiver =new EventReceiverDefinitionCreationInformation()
{
EventType = EventReceiverType.ItemAdded,
ReceiverAssembly = Assembly.GetExecutingAssembly().FullName,
ReceiverName = “ProductRemoteEventReceiver”,
ReceiverClass = “ProductRemoteEventReceiver”,
ReceiverUrl = remoteUrl,
SequenceNumber = 15000
};
//Add the remote event receiver to the host web list
documentsList.EventReceivers.Add(newEventReceiver);
clientContext.ExecuteQuery();
}
}
}
else if (properties.EventType == SPRemoteEventType.AppUninstalling)
{
using (ClientContext clientContext = TokenHelper.CreateAppEventClientContext(properties, false))
{
var list = clientContext.Web.Lists.GetByTitle(“Products”);
clientContext.Load(list);
clientContext.ExecuteQuery();
EventReceiverDefinitionCollection erdc = list.EventReceivers;
clientContext.Load(erdc);
clientContext.ExecuteQuery();
List<EventReceiverDefinition> toDelete = newList<EventReceiverDefinition>();
foreach (EventReceiverDefinition erd in erdc)
{
if (erd.ReceiverName == “ProductRemoteEventReceiver”)
{
toDelete.Add(erd);
}
}
//Delete the remote event receiver from the list, when the app gets uninstalled
foreach (EventReceiverDefinition item in toDelete)
{
item.DeleteObject();
clientContext.ExecuteQuery();
}
}
}
documentsList.EventReceivers.Add(newEventReceiver);
clientContext.ExecuteQuery();
}
}
}
else if (properties.EventType == SPRemoteEventType.AppUninstalling)
{
using (ClientContext clientContext = TokenHelper.CreateAppEventClientContext(properties, false))
{
var list = clientContext.Web.Lists.GetByTitle(“Products”);
clientContext.Load(list);
clientContext.ExecuteQuery();
EventReceiverDefinitionCollection erdc = list.EventReceivers;
clientContext.Load(erdc);
clientContext.ExecuteQuery();
List<EventReceiverDefinition> toDelete = newList<EventReceiverDefinition>();
foreach (EventReceiverDefinition erd in erdc)
{
if (erd.ReceiverName == “ProductRemoteEventReceiver”)
{
toDelete.Add(erd);
}
}
//Delete the remote event receiver from the list, when the app gets uninstalled
foreach (EventReceiverDefinition item in toDelete)
{
item.DeleteObject();
clientContext.ExecuteQuery();
}
}
}
return result;
}
}
}
}
ProcessOneWayEvent method:
ProcessEvent
is a synchronous event handler and is used to call code when a “before” event
occurs . ProcessOneWayEvent is an asynchronous event
handler and is used to call code when an “after” event occurs . My
code exists in ProcessOneWayEvent method as I am handling ItemAdded event here.
publicclassRemoteEventReceiver1 : IRemoteEventService
{
publicSPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
{
SPRemoteEventResult result = newSPRemoteEventResult();
using (ClientContext clientContext = TokenHelper.CreateRemoteEventReceiverClientContext(properties))
{
if (clientContext != null)
{
clientContext.Load(clientContext.Web);
clientContext.ExecuteQuery();
}
}
{
publicSPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
{
SPRemoteEventResult result = newSPRemoteEventResult();
using (ClientContext clientContext = TokenHelper.CreateRemoteEventReceiverClientContext(properties))
{
if (clientContext != null)
{
clientContext.Load(clientContext.Web);
clientContext.ExecuteQuery();
}
}
return result;
}
}
publicvoid ProcessOneWayEvent(SPRemoteEventProperties properties)
{
// On Item Added event, the list item creation executes
if(properties.EventType == SPRemoteEventType.ItemAdded){
using (ClientContext clientContext = TokenHelper.CreateRemoteEventReceiverClientContext(properties))
{
if (clientContext != null)
{
try
{
clientContext.Load(clientContext.Web);
clientContext.ExecuteQuery();
List imageLibrary = clientContext.Web.Lists.GetByTitle(“Products”);
ListItemCreationInformation itemCreateInfo = newListItemCreationInformation();
ListItem oListItem = imageLibrary.AddItem(itemCreateInfo);
oListItem[“Title”] = “TITLE CHANGED BY RER”;
oListItem.Update();
clientContext.ExecuteQuery();
}
catch (Exception ex){ }
}
}
}
}
{
// On Item Added event, the list item creation executes
if(properties.EventType == SPRemoteEventType.ItemAdded){
using (ClientContext clientContext = TokenHelper.CreateRemoteEventReceiverClientContext(properties))
{
if (clientContext != null)
{
try
{
clientContext.Load(clientContext.Web);
clientContext.ExecuteQuery();
List imageLibrary = clientContext.Web.Lists.GetByTitle(“Products”);
ListItemCreationInformation itemCreateInfo = newListItemCreationInformation();
ListItem oListItem = imageLibrary.AddItem(itemCreateInfo);
oListItem[“Title”] = “TITLE CHANGED BY RER”;
oListItem.Update();
clientContext.ExecuteQuery();
}
catch (Exception ex){ }
}
}
}
}
}
}
How It Works:
The SPRemoteEventResult object
that is returned to SharePoint. SharePoint honors any modification you made to
the object and updates the document list columns appropriately. It’s important
to note that although you must choose Trust It when your app is installed, when
using the SPRemoteEventResult object only, if your code is not
explicitly calling back into SharePoint using CSOM or REST to read/write data,
then you do not need to write code that uses the TokenHelper class.
This example shows the pattern where your remote event receiver can impact data
being written to SharePoint by modifying
the SPRemoteEventResult object directly.
Hope this post was
helpful! Millions of thanks for reading this blog.....happy
sharepoint....happy coding...
No comments:
Post a Comment