Crear un receptor de eventos remotos en Complementos de SharePoint

Es útil si primero tiene conocimientos de los complementos de SharePoint hospedados por el proveedor y para que haya desarrollado algunos que vayan al menos un poco más allá del nivel "Hola mundo". Vea Introducción a la creación de complementos de SharePoint hospedados por el proveedor.

Además, debe estar familiarizado con la sección Controlar eventos en los complementos de SharePoint.

Crear un receptor de eventos remoto

En este artículo se muestra cómo extender una Complemento de SharePoint al agregar un receptor de eventos remotos (RER) que controla el evento ItemAdded para una lista personalizada en la web de complemento. El RER está registrado con la web de complemento mediante el marcado declarativo. Los RER está registrados con la web de host mediante programación. Para obtener un ejemplo de código que lo haga, vea SharePoint/PnP/Samples/Core.EventReceivers.

Un RER debe ser un servicio web SOAP. En el ejemplo siguiente se implementa como un servicio de Windows Communication Foundation (WCF), pero en principio es posible implementar un RER en una pila que no sea de Microsoft.

Para seguir este artículo y escribir el código usted mismo, descargue el ejemplo de SharePoint-Add-in-CSOM-BasicDataOperations y, a continuación, abra el ejemplo en Visual Studio.

Nota:

En este ejemplo se usa un archivo TokenHelper.cs generado por Office Developer Tools para Visual Studio. Era la versión actual cuando se creó el ejemplo, pero puede que no sea la versión más reciente cuando lea esto. El ejemplo sigue siendo excelente para crear su primer RER. Pero cuando esté listo para ir más allá, debe examinar los ejemplos enumerados en la sección Ver también al final de este artículo. Es más probable que se mantengan actualizados.

Para registrar un receptor de eventos remotos

  1. Abra el proyecto de complemento de SharePoint en Visual Studio.

  2. En el Explorador de soluciones, seleccione el nodo del proyecto de complemento.

  3. En la barra de menús, seleccione Proyecto>Agregar nuevo elemento.

  4. En el panel Plantillas instaladas, seleccione el nodo Office/SharePoint.

  5. En el panel Plantillas, seleccione la plantilla Receptor de eventos remotos.

  6. En el cuadro Nombre, deje el nombre predeterminado (RemoteEventReceiver1) y luego seleccione Agregar.

  7. En la lista ¿Qué tipo de receptor de eventos desea usar?, seleccione Eventos de elementos de lista.

  8. En la lista ¿Qué elemento debe ser el origen del evento?, seleccione Lista personalizada.

    El ejemplo que continúa usa una lista genérica personalizada. Sin embargo, un RER también puede controlar eventos que ocurren en listas estándar de SharePoint, como Anuncios o Contactos.

  9. En la lista Controlar los siguientes eventos, seleccione Se va a agregar un elemento y, luego, Finalizar.

    Se agrega un servicio web a la aplicación web para controlar el evento remoto que especificó. Se agrega un receptor de eventos remotos al complemento de SharePoint y se hace referencia al evento de elemento de lista en el archivo de Elements.xml del receptor que se encuentra en la característica web del complemento.

Para crear la lista

  1. En el Explorador de soluciones, seleccione el nodo del proyecto de complemento.

  2. En la barra de menús, seleccione Proyecto>Agregar nuevo elemento.

  3. En el panel Plantillas instaladas, seleccione el nodo Office/SharePoint.

  4. En el panel Plantillas, seleccione la plantilla de Lista.

  5. En el cuadro Nombre, deje el nombre predeterminado (List1) y luego seleccione Agregar.

  6. Elija Crear una instancia de lista basada en una plantilla de lista existente, seleccione Lista personalizada en la lista y luego, Finalizar.

Para agregar una funcionalidad al receptor de eventos remotos

  1. Si la granja de sharePoint de prueba no está en el mismo equipo que ejecuta Visual Studio (o usa un inquilino de SharePoint Online como sitio de SharePoint de prueba), configure el proyecto para la depuración mediante el Microsoft Azure Service Bus. Para obtener más información, vea Depurar y solucionar problemas de un receptor de eventos remotos en un complemento de SharePoint.

  2. En el archivo de código para el servicio del receptor de eventos remotos (es decir, RemoteEventReceiver1.svc.cs), reemplace el contenido por el código siguiente. Este código realiza las siguientes tareas:

    • Obtiene un objeto de contexto de cliente válido.

    • Si no existe una lista llamada EventLog, crea una que contenga los nombres de los eventos remotos que se producen.

    • Agrega una entrada a la lista del evento, incluida una marca de hora y fecha.

    Nota:

    En el momento en que se escribió este artículo, Office Developer Tools para Visual Studio tenía referencias a todos los ensamblados necesarios cuando se crea el receptor, pero es posible que las versiones posteriores de las herramientas no. Si obtiene errores de compilador, bastará con agregar las referencias que faltan (por ejemplo, necesitará agregar referencias a System.ServiceModel o System.ComponentModel.DataAnnotations).

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Text;
    using Microsoft.SharePoint.Client;
    using Microsoft.SharePoint.Client.EventReceivers;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    
    namespace BasicDataOperationsWeb.Services
    {
        public class RemoteEventReceiver1 : IRemoteEventService
        {
            public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
            {
                // When a "before" event occurs (such as ItemAdding), call the event 
                // receiver code.
                ListRemoteEventReceiver(properties);
                return new SPRemoteEventResult();
            }
    
            public void ProcessOneWayEvent(SPRemoteEventProperties properties)
            {
                // When an "after" event occurs (such as ItemAdded), call the event 
                // receiver code.            
            }
    
            public static void ListRemoteEventReceiver(SPRemoteEventProperties properties)
            {
                string logListTitle = "EventLog";
    
                // Return if the event is from the EventLog list itself. Otherwise, it may go into
                // an infinite loop.
                if (string.Equals(properties.ItemEventProperties.ListTitle, logListTitle, 
                    StringComparison.OrdinalIgnoreCase))
                    return;
    
                // Get the token from the request header.
                HttpRequestMessageProperty requestProperty = 
                    (HttpRequestMessageProperty)OperationContext
                    .Current.IncomingMessageProperties[HttpRequestMessageProperty.Name];
                string contextTokenString = requestProperty.Headers["X-SP-ContextToken"];
    
                // If there is a valid token, continue.
                if (contextTokenString != null)
                {
                    SharePointContextToken contextToken =
                        TokenHelper.ReadAndValidateContextToken(contextTokenString, 
                            requestProperty.Headers[HttpRequestHeader.Host]);
    
                    Uri sharepointUrl = new Uri(properties.ItemEventProperties.WebUrl);
                    string accessToken = TokenHelper.GetAccessToken(contextToken, 
                                                        sharepointUrl.Authority).AccessToken;
                    bool exists = false;
    
                    // Retrieve the log list "EventLog" and add the name of the event that occurred
                    // to it with a date/time stamp.
                    using (ClientContext clientContext = 
                        TokenHelper.GetClientContextWithAccessToken(sharepointUrl.ToString(), 
                                                                                                            accessToken))
                    {
                        clientContext.Load(clientContext.Web);
                        clientContext.ExecuteQuery();
                        List logList = clientContext.Web.Lists.GetByTitle(logListTitle);
    
                        try
                        {
                            clientContext.Load(logList);
                            clientContext.ExecuteQuery();
                            exists = true;
                        }
    
                        catch (Microsoft.SharePoint.Client.ServerUnauthorizedAccessException)
                        {
                            // If the user doesn't have permissions to access the server that's 
                            // running SharePoint, return.
                            return;
                        }
    
                        catch (Microsoft.SharePoint.Client.ServerException)
                        {
                            // If an error occurs on the server that's running SharePoint, return.
                            exists = false;
                        }
    
                        // Create a log list called "EventLog" if it doesn't already exist.
                        if (!exists)
                        {
                            ListCreationInformation listInfo = new ListCreationInformation();
                            listInfo.Title = logListTitle;
                            // Create a generic custom list.
                            listInfo.TemplateType = 100;
                            clientContext.Web.Lists.Add(listInfo);
                            clientContext.Web.Context.ExecuteQuery();
                        }
    
                        // Add the event entry to the EventLog list.
                        string itemTitle = "Event: " + properties.EventType.ToString() + 
                            " occurred on: " + 
                            DateTime.Now.ToString(" yyyy/MM/dd/HH:mm:ss:fffffff");
                        ListCollection lists = clientContext.Web.Lists;
                        List selectedList = lists.GetByTitle(logListTitle);
                        clientContext.Load<ListCollection>(lists);
                        clientContext.Load<List>(selectedList);
                        ListItemCreationInformation listItemCreationInfo = 
                            new ListItemCreationInformation();
                        var listItem = selectedList.AddItem(listItemCreationInfo);
                        listItem["Title"] = itemTitle;
                        listItem.Update();
                        clientContext.ExecuteQuery();
                    }
                }
            }
        }
    }
    
  3. En Home.aspx.cs, cambie todas las instancias de SPHostUrl por SPAppWebUrl.

    Por ejemplo, sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]); tiene que cambiarse por sharepointUrl = new Uri(Request.QueryString["SPAppWebUrl"]);.

Ejecutar y probar el controlador de eventos

Siga este procedimiento para probar el controlador.

  1. Seleccione la tecla F5 para ejecutar el proyecto.

  2. Confíe en el complemento cuando se requiera. La Complemento de SharePoint se ejecutará y aparecerá una tabla de listas disponibles que incluye List1.

  3. Seleccione el identificador de List1. El ID se copia en el cuadro Recuperar elementos de lista.

  4. Seleccione el botón Recuperar elementos de lista . List1 aparecerá sin ningún elemento.

  5. En el cuadro Agregar elemento , especifique Primer elemento y, a continuación, seleccione el botón Agregar elemento . Se agregará un elemento llamado Primer elemento a List1, lo que hará que se inicie el receptor de eventos remoto y se agregue una entrada en la lista EventLog.

  6. Seleccione el botón Actualizar listas para volver a la tabla de listas. En la tabla, aparecerá una lista nueva llamada EventLog.

  7. Seleccione el valor de GUID ListID para EventLog y, a continuación, seleccione el botón Recuperar elementos de lista . Aparecerá una tabla para EventLog con una entrada para el evento Controlar ItemAdding que se produjo cuando agregó el elemento a List1.

Agregar o quitar controladores de eventos con Visual Studio

  1. En el Explorador de soluciones, seleccione el nodo de proyecto del receptor de eventos remotos.

  2. En el panel Propiedades, establezca las propiedades de los eventos que desea controlar en True.

    Por ejemplo, si desea responder cada vez que un usuario agregue un elemento de lista, establezca el valor de la propiedad Handle ItemAdding en True. Si no desea controlar ese evento, establezca el valor de esa propiedad en False.

    Eventos remotos de SharePoint en Visual Studio

    Eventos remotos de SharePoint en Visual Studio

  3. Si agregó un evento, agregue el código de control de eventos para el archivo de código del servicio web como lo hizo con eventos anteriores.

    Para controlar otro tipo de evento, agregue otro receptor de eventos remotos a la Complemento de SharePoint. Por ejemplo, si un receptor de eventos remotos controla los eventos de elementos de lista, puede agregarle otro evento de elementos de lista. Pero si desea controlar los eventos de la lista, deberá agregar otro receptor de eventos remotos.

Restricciones de URL y hospedaje para receptores de eventos remotos de producción

El destinatario del evento remoto puede estar hospedado en la nube o en un servidor local que no se use también como servidor de SharePoint. La dirección URL de un receptor de producción no puede especificar un puerto en concreto. Esto significa que se debe usar el puerto 443 para HTTPS (recomendado) o el puerto 80 para HTTP. Si usa HTTPS y el servicio del receptor se hospeda en el entorno local, pero el complemento está en SharePoint Online, el servidor host debe tener un certificado de confianza pública de una entidad de certificación. (Un certificado autofirmado solo funciona si el complemento está en una granja de SharePoint local).

Vea también