Eventos de complemento de identificador en el complemento hospedado por el proveedor
Este es el séptimo de una serie de artículos sobre los conceptos básicos de desarrollo de un Complementos de SharePoint hospedados por el proveedor. Primero debe familiarizarse con Complementos de SharePoint y con los anteriores artículos de esta serie, los cuales puede encontrar en Introducción a la creación de complementos de SharePoint hospedados por el proveedor.
Nota
Si a lo largo de esta serie ha estado trabajando sobre los complementos hospedados por el proveedor, tiene una solución de Visual Studio que puede usar para continuar con este tema. También puede descargar el repositorio que encontrará en SharePoint_Provider-hosted_Add-Ins_Tutorials y abrir el archivo BeforeAdd-inEventHandlers.sln.
En este artículo, se personaliza el control de un tipo de evento en SharePoint denominado eventos del complemento. En concreto, se crean controladores para los eventos de instalación y desinstalación de complementos. Los eventos de elementos de lista y de lista pueden obtener control personalizado. Obtendrá más información en un artículo posterior de esta serie. Todos estos eventos se desencadenan en SharePoint, pero el código personalizado que controla cada evento se encuentra en la aplicación web remota. Configure SharePoint para llamar a su controlador personalizado mediante el registro de la dirección URL del controlador con el evento de SharePoint.
Dos ubicaciones para implementar con programación componentes de SharePoint
Queremos que nuestro complemento Chain Store cree e implemente las listas de Empleados locales y Envíos esperados automáticamente. En cualquier momento un complemento puede implementar los componentes de SharePoint, como una lista personalizada. Pero cuando un complemento depende de un componente específico, como una lista personalizada, el componente se debe implementar verdaderamente antes de que los usuarios empiecen a trabajar con el complemento. Para estos componentes vitales, existen dos lugares a los que puede ir la lógica de implementación personalizada:
- En un controlador del evento de instalación del complemento.
- En la lógica "de primera vista" que se ejecuta la primera vez que se inicia el complemento en SharePoint.
Decidir qué es lo mejor para un complemento determinado es un tema avanzado. En este artículo, podemos mencionar solo algunos puntos de comparación:
Un controlador de instalación personalizada tiene que completarse en 30 segundos. No existe un límite para la duración de una lógica de primera vista.
Si algo va mal durante la instalación de un complemento, SharePoint revierte todo lo que se ha realizado como parte de la instalación. Se ejecuta un controlador de instalación personalizado después de que SharePoint haya finalizado todo lo necesario para instalar el complemento, de manera que un controlador personalizado pueda participar en este sistema.
Por ejemplo, si su lógica personalizada inicia una excepción, puede pedir a SharePoint que revierta la instalación completa del complemento. No obstante, si algo va mal con respecto a la lógica de primera ejecución personalizada, el complemento permanece instalado y es posible que no funcione correctamente.
SharePoint no cede si tiene que revertir una instalación del complemento. Intenta realizar la instalación de nuevo inmediatamente. Cuenta con un máximo de cuatro intentos (el límite de 30 segundos se aplica en cada intento). Cada vez que lo reintenta, el controlador de instalación personalizado se ejecuta de nuevo desde el principio. Si el controlador logró instalar una lista antes de revertir, intenta instalar de nuevo la lista en el reintento.
Para evitar que esto ocurra, se tiene que escribir el código de un controlador de instalación para que no haga nada (por ejemplo, implementar un componente) a menos que primero compruebe si ya ha realizado esta acción. Esto hace que la lógica de un controlador de instalación sea más compleja que la lógica de primera ejecución porque la lógica de primera ejecución no lo intentará de nuevo (a menos que se codifique específicamente para hacerlo). Además, para comprobar si un componente ya se ha implementado se suele necesitar una llamada que requiera mucho tiempo en Internet desde el controlador remoto a SharePoint. También se necesita una segunda llamada para implementar el componente (si no se ha implementado todavía).
Para el complemento Chain Store, combinamos estas estrategias. En este artículo, se crea un controlador de instalación que registra la web de host como inquilino en la base de datos corporativa y, a continuación, establece una señal que especifica si el complemento se ha ejecutado ya en la web de host.
En un artículo posterior de esta serie, colocará la lógica de primera ejecución en el método Page_Load de la página de inicio de los complementos. Esta lógica implementa las dos listas personalizadas y hace algunas otras cosas también.
Configurar la solución para la depuración del receptor de eventos
La depuración de los receptores de eventos necesita el uso de Azure Service Bus. Siga las instrucciones en Depurar y solucionar problemas de un receptor de eventos remotos en un complemento de SharePoint. Debido a que se usa un sitio web de SharePoint Online como sitio de prueba, asegúrese de seguir las instrucciones de un sitio de prueba remoto. El resto de esta serie supone que ha configurado correctamente la depuración.
Crear el controlador de instalación
Nota
The settings for Startup Projects in Visual Studio tend to revert to defaults whenever the solution is reopened. Always take these steps immediately after reopening the sample solution in this series of articles:
- Haga clic con el botón derecho en el nodo de la solución en la parte superior del Explorador de soluciones y después seleccione Establecer proyectos de inicio.
- Asegúrese de que los tres proyectos estén establecidos en Iniciar en la columna Acción.
En el Explorador de soluciones, seleccione el proyecto ChainStore para mostrar sus propiedades en el panel Propiedades de Visual Studio.
Establezca el valor de Complemento de identificador instalado en True (puede que siga llamándose Aplicación de identificador instalada). Esto hace dos cosas:
Se crea una carpeta llamada Servicios en el proyecto ChainStoreWeb (no en el proyecto ChainStore), donde se agregan dos archivos: un archivo AppEventReceiver.svc y su archivo de código subyacente AppEventReceiver.svc.cs (los nombres de archivo empiezan por la cadena "App" porque los complementos solían llamarse "aplicaciones". No cambie el nombre de estos archivos porque Office Developer Tools para Visual Studio da por hecho que los archivos conservarán estos nombres).
La dirección URL del controlador se ha registrado en el manifiesto del complemento. Esta parte del manifiesto no está visible en el diseñador de manifiesto. Para verlo, haga clic en el archivo AppManifest.xml y seleccione Ver código. Un nuevo elemento secundario del elemento Propiedades tiene un aspecto parecido al siguiente.
<InstalledEventEndpoint>~remoteAppUrl/Services/AppEventReceiver.svc</InstalledEventEndpoint>
Este marcado indica a SharePoint que llame al método ProcessEvent de este servicio cuando termine de realizar su propio trabajo relacionado con la instalación del complemento. El controlador personalizado es lo último que se ejecuta como parte de la instalación. La cadena
~remoteAppUrl
es un marcador de posición que Office Developer Tools para Visual Studio reemplaza con la URL de host de servicio. Al depurar, es una dirección URL de Azure Service Bus. Al crear el paquete de implementación de producción, es la dirección URL de producción.
Abra el archivo AppEventReceiver.svc.cs.
Verá que Office Developer Tools para Visual Studio ha creado una implementación de ejemplo del método ProcessEvent. Todas las implementaciones de este método comienzan al iniciarse el objeto SPRemoteEventResult y todas finalizan volviendo a objeto a SharePoint. Entre otras cosas, este objeto indica a SharePoint si debe revertir o no el evento porque se produce un error en la lógica de control personalizada.
Las herramientas también podrían haber incluido un bloque using en este método que crea un objeto ClientContext. El controlador personalizado en el complemento Chain Store no va a devolver la llamada en SharePoint, así que elimine este bloque. El método tendrá la siguiente apariencia.
public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties) { SPRemoteEventResult result = new SPRemoteEventResult(); return result; }
Cualquiera de los tres eventos de complementos posibles podría llamar al receptor de eventos. Por lo tanto, agregue la siguiente estructura switch al método ProcessEvent entre las líneas que crean y devuelven el objeto
result
. Los nombres de evento tienen la cadena "App" porque los complementos solían llamarse "aplicaciones".switch (properties.EventType) { case SPRemoteEventType.AppInstalled: // TODO2: Custom installation logic goes here. break; case SPRemoteEventType.AppUpgraded: // This sample does not implement an add-in upgrade handler. break; case SPRemoteEventType.AppUninstalling: // TODO3: Custom uninstallation logic goes here. break; }
La lógica de instalación va a llamar a un procedimiento almacenado de SQL para registrar la tienda Hong Kong como inquilino en la aplicación web remota. Es muy importante que, si este proceso produce un error, el controlador indique a SharePoint que revierta la instalación el complemento, así que agregue los siguientes bloques try/catch en lugar de
TODO2
.try { CreateTenant(tenantName); } catch (Exception e) { // Tell SharePoint to cancel and roll back the event. result.ErrorMessage = e.Message; result.Status = SPRemoteEventServiceStatus.CancelWithError; }
Tenga en cuenta lo siguiente en relación con este código:
- Cree el objeto
tenantName
y el métodoCreateTenant
en un paso posterior. - La propiedad Status del objeto SPRemoteEventResult puede tener tres valores posibles: Continue (predeterminado), CancelNoError y CancelWithError. Cualquiera de los dos últimos indicará a SharePoint que revierta el evento.
- Cree el objeto
La dirección URL web de host, que es discriminador del inquilino de ejemplo, forma parte de la información que SharePoint pasa al receptor en el parámetro SPRemoteEventProperties. Agregue la línea siguiente al método ProcessEvent en la línea que está justo debajo de inicializar el objeto SPRemoteEventResult.
string tenantName = properties.AppEventProperties.HostWebFullUrl.ToString();
Ahora nuestro código debe tratar con una pequeña rareza de la propiedad AppEventProperties.HostWebFullUrl. En otros contextos, SharePoint incluye un carácter de cierre
"/"
al final de la dirección URL web de host, por lo que el valor lógico del código de nuestro ejemplo supone que este carácter está presente. Pero SharePoint agrega este carácter al final del valor HostWebFullUrl si, y solo si, la web de host es la web raíz de una colección de sitios. Debido a que nuestro sitio web de Hong Kong es una subweb en la colección de sitios, es necesario agregar este carácter para asegurarse de que se utiliza la misma cadena de nombre de inquilino en el ejemplo.Agregue el código siguiente después de iniciar el objeto de
tenantName
.if (!tenantName.EndsWith("/")) { tenantName += "/"; }
Agregue las siguientes instrucciones using al principio del archivo.
using System.Data.SqlClient; using System.Data; using ChainStoreWeb.Utilities;
Agregue el método siguiente a la clase
AppEventReceiver
. No trataremos esto en detalle porque el objetivo de esta serie de artículos es enseñar programación de complementos de SharePoint, no programación de SQL Server/Azure.private void CreateTenant(string tenantName) { // Do not catch exceptions. Allow them to bubble up and trigger roll back // of installation. using (SqlConnection conn = SQLAzureUtilities.GetActiveSqlConnection()) using (SqlCommand cmd = conn.CreateCommand()) { conn.Open(); cmd.CommandText = "AddTenant"; cmd.CommandType = CommandType.StoredProcedure; SqlParameter name = cmd.Parameters.Add("@Name", SqlDbType.NVarChar); name.Value = tenantName; cmd.ExecuteNonQuery(); }//dispose conn and cmd }
Este método crea una fila en una tabla de base de datos denominada Inquilinos. Además de la columna Nombre, la tabla también contiene una columna Versión con el valor predeterminado establecido en 0000.0000.0000.0000. En un artículo posterior de esta serie, creará una lógica de primera ejecución que examina este valor para determinar si el complemento ya se ha instalado en la web de host. Si la versión es 0000.0000.0000.0000, el código implementa las listas Empleados locales y Envíos esperados y, a continuación, aumenta el número de versión.
Crear el controlador de desinstalación
Normalmente es una buena práctica para controlar el evento de desinstalación cuando controla el evento instalado. La idea básica es que el controlador de desinstalación elimine o recicle cosas que ha implementado el controlador instalado. Hay, sin embargo, muchas excepciones, por lo que tiene que entender los casos de uso de un complemento. Por ejemplo, es posible que una lista que se implementa con un complemento y se rellena con el complemento siga teniendo valor incluso después de que el complemento se haya desinstalado, en cuyo caso no querrá desinstalar la lista en el controlador de eventos de desinstalación.
No se ejecuta el evento de desinstalación, como se esperaba, cuando un usuario elimina el complemento de la página Contenidos del sitio. Con esto solo se mueve el complemento a la Papelera de reciclaje del sitio web. Un usuario puede restaurarlo, pero la restauración no volverá a ejecutar el controlador de eventos instalado, por lo que querrá que todo lo que se implementó con un controlador de eventos instalado siga existiendo si se restaura el complemento. Los componentes de SharePoint se pueden mover de la Papelera de reciclaje a la Papelera de reciclaje de segundo nivel. Es solo cuando un complemento se elimina de la segunda etapa que se produce el evento de desinstalación. Cuando un usuario lo hace, el complemento igualmente no se puede restaurar, por lo que queremos que el arrendamiento de la tienda Hong Kong se elimine de la base de datos corporativa en ese momento.
Establezca el valor de Desinstalación del complemento de identificador en True (puede que siga llamándose Desinstalación de la aplicación de identificador). Registra el controlador en el archivo AppManifest.xml igual que anteriormente registró el controlador de instalación. Si observa el archivo, verá que tienen exactamente la misma dirección URL. Office Developer Tools para Visual Studio asume que usa el mismo archivo *.svc. Lo estamos haciendo en este ejemplo, y es una práctica estándar.
Agregue el código siguiente en lugar de
TODO3
en el archivo AppEventReceiver.svc.cs.try { DeleteTenant(tenantName); } catch (Exception e) { // Tell SharePoint to cancel and roll back the event. result.ErrorMessage = e.Message; result.Status = SPRemoteEventServiceStatus.CancelWithError; }
Tenga en cuenta lo siguiente en relación con este código:
- El método
DeleteTenant
se agregará en el paso siguiente. - Al revertir la desinstalación del complemento, este se queda en la Papelera de reciclaje de segundo nivel, desde donde aún podría restaurarse.
- El método
Agregue el método siguiente a la clase
AppEventReceiver
.private void DeleteTenant(string tenantName) { // Do not catch exceptions. Allow them to bubble up and trigger roll back // of un-installation (removal from 2nd level Recycle Bin). using (SqlConnection conn = SQLAzureUtilities.GetActiveSqlConnection()) using (SqlCommand cmd = conn.CreateCommand()) { conn.Open(); cmd.CommandText = "RemoveTenant"; cmd.CommandType = CommandType.StoredProcedure; SqlParameter name = cmd.Parameters.Add("@Name", SqlDbType.NVarChar); name.Value = tenantName; cmd.ExecuteNonQuery(); }//dispose conn and cmd }
Nota
En un artículo anterior de esta serie, configuró el proyecto para recompilar la base de datos corporativa cada vez que selecciona F5. Esto vacía la tabla Inquilinos.
Ejecutar el complemento y probar el controlador de instalación
Use la tecla F5 para implementar y ejecutar el complemento. Visual Studio hospeda la aplicación web remota en IIS Express y hospeda la base de datos SQL en SQL Express. También instala temporalmente el complemento en el sitio de SharePoint de prueba, ejecuta el controlador de eventos de instalación, y ejecuta el complemento inmediatamente. Se le solicitará que conceda permisos al complemento antes de que se abra su página de inicio.
Cuando se abra la página de inicio del complemento, seleccione el icono de engranaje en el control de cromo de la parte superior y, a continuación, seleccione Configuración de la cuenta.
En la página Configuración de las cuentas, seleccione el botón Mostrar versión del complemento. Esta versión se muestra como 0000.0000.0000.0000.
Figura 1: Página de configuración de la cuenta
To end the debugging session, close the browser window or stop debugging in Visual Studio. Each time that you select F5, Visual Studio retracts the previous version of the add-in and installs the latest one.
Trabajará con este complemento y con la solución Visual Studio en otros artículos, y se considera recomendable retirar el complemento una última vez cuando acabe de trabajar en él durante un tiempo. En el proyecto, haga clic con el botón derecho en Explorador de soluciones y seleccione Retirar.
Pasos siguientes
En el siguiente artículo de la serie, agregaremos la lógica de la primera vista al complemento que implementa mediante programación la lista Empleados locales y el botón personalizado de la cinta de opciones: Agregar lógica de la primera vista al complemento hospedado por el proveedor.