SharePoint 2013: Como crear un manejador de eventos remoto (I)!

Hace unos meses os hablaba sobre las novedades en manejadores de eventos que tenemos en SharePoint 2013, poniendo foco en el soporte de manejadores de eventos remotos que se definen como servicios WCF que facilitan que las aplicaciones del nuevo modelo de aplicaciones puedan responder a eventos que tienen lugar en elementos típicos de SharePoint como sitios, listas o elementos de lista de forma similar a lo que podemos hacer con los manejadores de eventos convencionales. Los manejadores de eventos remotos se soportan en los tres tipos de aplicaciones del modelo de aplicaciones de SharePoint 2013:

  • Provider-Hosted, es decir, las aplicaciones están provisionadas en un servidor dedicado.
  • Autohosted, es decir, las aplicaciones están provisionadas en Windows Azure.
  • SharePoint Hosted, es decir, las aplicaciones están provisionadas en una colección de sitios independiente definida por aplicación web y denominada catálogo de aplicaciones.

Como comenté en el post inicial, en Visual Studio 2012 y en las herramientas de desarrollo para SharePoint/Office tenemos una plantilla específica para crear un manejador de eventos remoto. El proceso a seguir sería:

  • Crear un proyecto de tipo Aplicación para SharePoint 2013. En mi caso, elegir como tipo de aplicación “Hospedado por SharePoint” (SharePoint Hosted).
  • Añadir al proyecto un elemento de tipo Receptor de eventos remotos (Remote Event Receiver), lo que crea a nivel de Visual Studio 2012 un proyecto web con el servicio WCF que implementa el manejador de eventos remoto.
  • Codificar los dos métodos ya explicados en el post anterior, con la sutil diferencia de qué a nivel de modelo de objetos ha habido algunos cambios a tener en cuenta.
Capitulo14_Figura2 Capitulo14_Figura3

A nivel de cambios del modelo de objetos, nos encontraremos conque:

  • La clase manejadora hereda de la interfaz IRemoteEventService que está definida dentro de un nuevo espacio de nombres using Microsoft.SharePoint.Client.EventReceivers;
  • En lugar de trabajar con RemoteEventProperties, tendremos SPRemoteEventProperties y para detectar el tipo de evento tendreos SPRemoteEventType en lugar de RemoteEventType.
  • Dicho esto, la codificación es idéntica para los métodos ProcessEvent() (para eventos de tipo síncrono) y ProcessOneWayEvent() que implementa la clase manejadora:
    • Para una lista de tipo personalizado, una implementación de ejemplo de ProcessEvent() es:
   1:          public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
   2:          {
   3:              SPRemoteEventResult result = new SPRemoteEventResult();
   4:   
   5:              switch (properties.EventType)
   6:              {
   7:                  case SPRemoteEventType.ItemAdding:
   8:                      result.ChangedItemProperties.Add(
   9:                          "Title",
  10:                          properties.ItemEventProperties.AfterProperties["Title"] +=
  11:                          " - Añadiendo Elemento");
  12:                      break;
  13:                  case SPRemoteEventType.ItemDeleting:
  14:                      result.ErrorMessage =
  15:                          "No se pueden elminar elementos de esta lista";
  16:                      result.Status =
  17:                          SPRemoteEventServiceStatus.CancelWithError;
  18:                      break;
  19:                  default:
  20:                      break;
  21:              }
  22:              
  23:              return result;
  24:          }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

    • Y para ProcessOneWayEvent() tendríamos:
   1:          public void ProcessOneWayEvent(SPRemoteEventProperties properties)
   2:          {
   3:              if (properties.EventType == SPRemoteEventType.ItemAdded)
   4:              {
   5:                  using (ClientContext ctx = new ClientContext(
   6:                      properties.ItemEventProperties.WebUrl))
   7:                  {
   8:                      List lList =
   9:                          ctx.Web.Lists.GetByTitle(
  10:                              properties.ItemEventProperties.ListTitle);
  11:                      ctx.Load(lList);
  12:                      ListItem liItem =
  13:                          lList.GetItemById(
  14:                              properties.ItemEventProperties.ListItemId);
  15:                      ctx.Load(liItem);
  16:                      ctx.ExecuteQuery();
  17:                      liItem["Title"] +=
  18:                          " - Elemento Añadido";
  19:   
  20:                      liItem.Update();
  21:                      ctx.ExecuteQuery();
  22:                  }
  23:              }
  24:          }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Fijaros con como en ProcessOneWayEvent() hacemos uso del modelo de objetos en cliente para actualizar el elemento de lista una vez que se ha añadido. Y  hasta aquí llega este primer post sobre creación de manejadores de eventos remotos.