Agregar lógica de primera ejecución al complemento hospedado por el proveedor
Este es el octavo 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 BeforeFirstRunLogic.sln.
En este artículo, puede agregar código a la página de inicio del complemento de SharePoint Chain Store para comprobar si la instancia actual del complemento se ejecuta por primera vez. Si es la primera vez, el código implementa la lista de empleados locales y el botón personalizado de la cinta de opciones.
Crear la clase básica para implementar componentes de SharePoint
Nota:
La configuración de inicio de proyectos en Visual Studio tiende a revertir a los valores predeterminados cada vez que la solución se vuelve a abrir. Siempre debe seguir estos pasos inmediatamente después de abrir de nuevo la solución de ejemplo de esta serie de artículos:
- 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 proyecto ChainStoreWeb del Explorador de soluciones, haga clic con el botón derecho en la carpeta Utilidades y seleccione Agregar>Elemento existente.
En el Explorador de archivos, vaya a la carpeta de soluciones, abra la carpeta ChainStoreWeb y, después, la carpeta Utilidades.
Seleccione SharePointComponentDeployer.cs y, a continuación, seleccione Agregar.
Abra el archivo SharePointComponentDeployer.cs. Tiene una clase estática y dos métodos estáticos que obtienen y establecen la versión del complemento en la tabla Inquilinos de la base de datos corporativa. No analizaremos estos métodos porque esta serie de artículos no está diseñada para enseñar programación ASP.NET o SQL Server/Azure.
Agregue las siguientes instrucciones using al principio del archivo.
using System.Web; using System.Linq; using System.Collections.Generic; using Microsoft.SharePoint.Client;
En la parte superior de la clase
SharePointComponentDeployer
, agregue los dos campos siguientes estáticos. Estos dos campos se inicializan en el método Page_Load de la página de inicio del complemento (agregaremos el código en un paso posterior).internal static SharePointContext sPContext; internal static Version localVersion;
Tenga en cuenta lo siguiente en relación con este código:
El primer campo contiene el objeto
SharePointContext
, que es necesario para realizar operaciones CRUD en SharePoint.El segundo campo contiene el número de versión del complemento que se instala en la web de host. Este valor es diferente al principio del valor predeterminado (0000.0000.0000.0000) que se registra en la tabla corporativa Inquilinos cuando el controlador de la instalación registra el inquilino. Por ejemplo, la primera versión del complemento será 1.0.0.0.
Cree la siguiente propiedad estática para mantener la versión del complemento que se encuentra registrada actualmente en la tabla corporativa Inquilinos. Usa los dos métodos que ya estaban en el archivo para obtener y establecer este valor.
internal static Version RemoteTenantVersion { get { return GetTenantVersion(); } set { SetTenantVersion(value); } }
Ahora, cree la siguiente propiedad
IsDeployed
.public static bool IsDeployed { get { if (RemoteTenantVersion < localVersion) return false; else return true; } }
Tenga en cuenta lo siguiente en relación con este código:
El método Page_Load de la página de inicio del complemento es el valor de esta propiedad para determinar si el complemento se ejecuta por primera vez. Un valor false indica que el complemento no se ha ejecutado antes en la web de host actual, por lo que sus componentes deben implementarse.
El criterio es si el número de versión registrado en la tabla Inquilinos es inferior a la versión instalada en ese momento. La primera vez que el complemento se ejecuta es inferior. El código que se escribe en un paso posterior establece la versión de la tabla Inquilinos en la misma versión mientras se instala realmente, por lo que cuando el complemento se ejecuta,
IsDeployed
devuelve true y la lógica de implementación no se vuelve a ejecutar.
Agregue el método siguiente a la clase
SharePointComponentDeployer
. Tenga en cuenta que lo último que el método hace es actualizar la versión del inquilino registrada en la base de datos corporativa (0000.0000.0000.0000) para que coincida con la versión real del complemento en la web de host (1.0.0.0). Completará este método en un paso posterior.internal static void DeployChainStoreComponentsToHostWeb(HttpRequest request) { // TODO4: Deployment code goes here. RemoteTenantVersion = localVersion; }
Nota:
Puede preguntarse ahora por qué el complemento usa números de versión y una prueba "menor que" para determinar la respuesta a una pregunta simple sí/no: "¿Se ejecuta el complemento por primera vez?". También podríamos tener un campo de cadena simple en la tabla Tenants que está establecido en no ejecutarse todavía en el controlador de instalación y, a continuación, cambiar a ya ejecutado una vez por la lógica de primera ejecución después de implementar los componentes de SharePoint.
Para el complemento Chain Store, una simple prueba funcionaría. Sin embargo, generalmente es recomendable usar números de versión debido a que es probable que un complemento de producción se actualice en contexto en el futuro, es decir, se actualiza después de que esté instalado. Cuando llega ese momento, la lógica del complemento debe ser consciente de más de las dos posibilidades no ejecutar todavía y ejecutado una vez.
Por ejemplo, supongamos que desea agregar una lista adicional a la web de host en la actualización de la versión 1.0.0.0 a la 2.0.0.0. Puede hacerlo en un controlador de eventos de la actualización o en la lógica de primera ejecución después de la actualización. En ambos casos, la lógica de implementación necesita nuevos componentes para implementar, pero también debe evitar intentar implementar los componentes que se implementaron en una versión anterior del complemento. El número de versión 1.0.0.0 indica que se han implementado los componentes de la versión 1.0.0.0, pero que no se ha ejecutado todavía la lógica de primera ejecución después de actualizar.
Agregar la lógica de inicio básica
La web de host de SharePoint debe informar a la aplicación web remota acerca de qué versión del complemento se ha instalado. Para ello, usamos un parámetro de consulta.
Abra el archivo AppManifest.xml en el proyecto ChainStore. En el diseñador, verá el marcador de posición {StandardTokens} como valor del cuadro Cadena de consulta. Agregue la cadena
"&SPAddInVersion=1.0.0.0"
al final.El diseñador del manifiesto será similar al siguiente. Observe que el número de versión que pasa en la cadena de consulta debe coincidir con el valor del cuadro Versión del diseñador . Si alguna vez actualiza el complemento, una de las tareas es aumentar estos dos valores y mantenerlos.
Figura 1. Pestaña General del diseñador de manifiestos
Abra el archivo CorporateDataViewer.aspx.cs y agregue el código siguiente al método Page_Load, justo debajo de la línea que inicializa el objeto
spContext
.SharePointComponentDeployer.sPContext = spContext; SharePointComponentDeployer.localVersion = new Version(Request.QueryString["SPAddInVersion"]); if (!SharePointComponentDeployer.IsDeployed) { SharePointComponentDeployer.DeployChainStoreComponentsToHostWeb(Request); }
Tenga en cuenta lo siguiente en relación con este código:
Comienza con la configuración de los dos campos estáticos en la clase estática
SharePointComponentDeployer
. Pasa el objeto SharePointContext porque el código en elSharePointComponentDeployer
llamará a SharePoint y usa el parámetro de consulta que agregó para establecer la propiedadlocalVersion
.No hace nada si
IsDeployed
es verdadero, es decir, si ya ha ejecutado la lógica de primera ejecución. En caso contrario, llama al método de implementación y pasa el objeto de Solicitud de ASP.NET.
Implementar con programación una lista de SharePoint
En el archivo SharePointComponentDeployer.cs, cambie
TODO4
por la línea siguiente (puede crear este método en el paso siguiente).CreateLocalEmployeesList();
Agregue el método siguiente a la clase
SharePointComponentDeployer
.private static void CreateLocalEmployeesList() { using (var clientContext = sPContext.CreateUserClientContextForSPHost()) { var query = from list in clientContext.Web.Lists where list.Title == "Local Employees" select list; IEnumerable<List> matchingLists = clientContext.LoadQuery(query); clientContext.ExecuteQuery(); if (matchingLists.Count() == 0) { // TODO5: Create the list // TODO6: Rename the Title field on the list // TODO7: Add "Added to Corporate DB" field to the list clientContext.ExecuteQuery(); } } }
Tenga en cuenta lo siguiente en relación con este código:
Tiene dos llamadas de ExecuteQuery. La primera es necesaria para determinar si la lista ya existe. La segunda se encarga de crear la lista.
El método ClientContext.LoadQuery es similar al método ClientContext.Load, excepto que, en lugar de incluir una entidad (como una lista) en el cliente, incluye los resultados numerables de una consulta.
Cambie
TODO5
por el código siguiente.ListCreationInformation listInfo = new ListCreationInformation(); listInfo.Title = "Local Employees"; listInfo.TemplateType = (int)ListTemplateType.GenericList; listInfo.Url = "Lists/Local Employees"; List localEmployeesList = clientContext.Web.Lists.Add(listInfo);
Tenga en cuenta lo siguiente en relación con este código:
La clase ListCreationInformation es similar a la clase ListItemCreationInformation que vio en un artículo anterior de esta serie. Es una clase ligera más adecuada para enviar la información de la aplicación web a SharePoint que la clase completa Lista.
Existen muchos tipos de plantillas de lista, como el tipo Tareas para una lista "para hacer" y el tipo Eventos para un calendario. La lista Empleados locales se basa en la más sencilla: la de tipo Genérica.
La propiedad ListCreationInformation.Url contiene la dirección URL de la lista relativa en la web de host. Especificando
"Lists/LocalEmployees"
, el código establece la dirección URL completa de la lista parahttps://{SharePointDomain}/hongkong/_layouts/15/start.aspx#/Lists/Local%20Employees
.
Reemplace por
TODO6
el código siguiente, que cambia el nombre público del campo "Título" (columna) de "Título" a "Nombre". Esto es lo que hizo en la página Configuración de lista cuando creó la lista manualmente.Field field = localEmployeesList.Fields.GetByInternalNameOrTitle("Title"); field.Title = "Name"; field.Update();
Ha creado manualmente un campo llamado Agregado a BD corporativa. Para ello mediante programación, agregue el código siguiente en lugar de
TODO7
.localEmployeesList.Fields.AddFieldAsXml("<Field DisplayName='Added to Corporate DB'" +"Type='Boolean'>" + "<Default>FALSE</Default></Field>", true, AddFieldOptions.DefaultValue);
Tenga en cuenta lo siguiente en relación con este código:
Las propiedades clave del campo se especifican con un blob de XML. Se trata de una herencia de la arquitectura de SharePoint, donde se definen como XML los sitios web, las listas, los campos, y otros tipos de componentes de SharePoint. En este caso, especificamos el nombre para mostrar, el tipo de datos y el valor predeterminado del campo.
El segundo parámetro determina si el campo es visible en la vista predeterminada de la lista. Lo establecemos en true.
El tercer parámetro determina a qué tipos de contenido se agrega el campo. Pasar DefaultValue significa que solo se agrega al tipo de contenido predeterminado de la lista.
Recuerde que Agregado a BD corporativa es No (es decir, falso) de forma predeterminada, pero el botón personalizado de la cinta de opciones del complemento está establecido en Sí cuando se agrega al empleado a la base de datos corporativa. Este sistema funciona mejor si los usuarios no pueden cambiar manualmente el valor del campo. Para asegurarse de que no es así, hacen invisible al campo en los formularios para crear y editar elementos en la lista Empleados locales. Para ello, agregue dos atributos más al primer parámetro, como se muestra en el siguiente código.
localEmployeesList.Fields.AddFieldAsXml("<Field DisplayName='Added to Corporate DB'" + " Type='Boolean'" + " ShowInEditForm='FALSE' " + " ShowInNewForm='FALSE'>" + "<Default>FALSE</Default></Field>", true, AddFieldOptions.DefaultValue);
El elemento
CreateLocalEmployeesList
completo ahora debería ser similar al siguiente.private static void CreateLocalEmployeesList() { using (var clientContext = sPContext.CreateUserClientContextForSPHost()) { var query = from list in clientContext.Web.Lists where list.Title == "Local Employees" select list; IEnumerable<List> matchingLists = clientContext.LoadQuery(query); clientContext.ExecuteQuery(); if (matchingLists.Count() == 0) { ListCreationInformation listInfo = new ListCreationInformation(); listInfo.Title = "Local Employees"; listInfo.TemplateType = (int)ListTemplateType.GenericList; listInfo.Url = "LocalEmployees"; List localEmployeesList = clientContext.Web.Lists.Add(listInfo); Field field = localEmployeesList.Fields.GetByInternalNameOrTitle("Title"); field.Title = "Name"; field.Update(); localEmployeesList.Fields.AddFieldAsXml("<Field DisplayName='Added to Corporate DB'" + " Type='Boolean'" + " ShowInEditForm='FALSE' " + " ShowInNewForm='FALSE'>" + "<Default>FALSE</Default></Field>", true, AddFieldOptions.DefaultValue); clientContext.ExecuteQuery(); } } }
Quitar de forma temporal el botón personalizado del proyecto
Por razones técnicas que abordaremos en el siguiente artículo, no se puede instalar el botón personalizado que creamos sin modificaciones cuando se coloca en la cinta de opciones de una lista que se implementa mediante programación. Se le quitará temporalmente del proyecto para que podamos probar la lógica de primera ejecución. La recordaremos en el artículo siguiente.
- En el Explorador de soluciones, en el proyecto ChainStore, haga clic con el botón derecho en el nodo AddEmployeeToCorpDB y seleccione Excluir del proyecto.
Solicitar permiso para administrar listas en la web de host
Dado que el complemento ahora agrega una lista a la web de host, no solo elementos a una lista existente, debemos elevar los permisos que el complemento solicita de Escribir a Administrar:
En el Explorador de soluciones, abra el archivo AppManifest.xml en el proyecto ChainStore.
En la pestaña Permisos, deje el valor de Ámbito en Web; pero, en el campo Permiso, seleccione Administrar en el menú desplegable.
Guarde el archivo.
Ejecutar el complemento y probar la lógica de primera ejecución
Abra la página Contenidos del sitio del sitio web de la tienda Hong Kong y, a continuación, elimine la lista Empleados locales.
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 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 vínculo Volver al sitio en el control de cromo de la parte superior.
Vaya a la página Contenidos del sitio. La lista Empleados locales está presente porque la lógica de primera ejecución la agregó.
Nota:
Si la lista no existe o tiene otras indicaciones de que el código de primera ejecución no se está ejecutando, es posible que la tabla Inquilinos no vuelva a un estado vacío al seleccionar F5. La causa más común de esto es que el proyecto ChainCorporateDB ya no está establecido como un proyecto de inicio en Visual Studio. Consulte la nota en la parte superior de este artículo sobre cómo solucionar este problema. Además, asegúrese de que ha configurado la base de datos para que se recopile como se describe en Configurar Visual Studio para recompilar la base de datos corporativa con cada sesión de depuración.
Abra la lista y agregue un elemento. Tenga en cuenta que, en el formulario de nuevo elemento, el campo Agregado a BD corporativa ya no está presente, por lo que no se puede establecer manualmente. Esto también ocurre con el formulario de edición de elemento.
Figura 2. Nuevo formulario de elemento para la lista Empleados locales
Use el botón volver del explorador para volver a la página de inicio del complemento.
Seleccione el icono de engranaje el control de cromo de la parte superior y, a continuación, seleccione Configuración de la cuenta.
En la página de Configuración de la cuenta, seleccione el botón Mostrar versión del complemento. La versión se muestra como 1.0.0.0 porque la lógica de primera ejecución la ha cambiado.
Figura 3. Página configuración de la cuenta
Para finalizar la sesión de depuración, cierre la ventana del explorador o detenga la depuración en Visual Studio. Cada vez que seleccione F5, Visual Studio retira la versión anterior del complemento e instala la más reciente.
Trabajará con este complemento y con la solución de Visual Studio en otros artículos. Es recomendable que vuelva a retirar el complemento cuando deje de trabajar con él por un tiempo. Haga clic con el botón derecho en el proyecto en el Explorador de soluciones y seleccione Retirar.
Pasos siguientes
En el siguiente artículo, veremos cómo incorporar el botón personalizado para la cinta de opciones Empleados locales otra vez en el complemento ahora que se implementa la lista mediante programación: Implementar mediante programación un botón personalizado en el complemento hospedado por el proveedor.