Compartir a través de


Llamar a servicios web desde flujos de trabajo de SharePoint

Puede utilizar el modelo de complemento de SharePoint para crear e implementar flujos de trabajo que se ejecuten en la web del complemento o en la web del host. Estos flujos de trabajo pueden interactuar con las partes alojadas a distancia de los complementos alojados por el proveedor.

Los flujos de trabajo también pueden llamar a servicios web remotos que contienen datos empresariales importantes de una de estas dos formas:

  • Al pasar la información de la consulta a la parte alojada de forma remota del complemento. La aplicación web remota llama al servicio web y devuelve la información a SharePoint.

  • AL consultar el servicio web mediante el proxy web de SharePoint. El flujo de trabajo pasa los resultados de la consulta a la parte alojada de forma remota del complemento, que luego pasa la información a SharePoint.

La información recuperada del servicio web puede almacenarse en listas de SharePoint.

En este artículo se describen tres ejemplos de código que muestran cómo llamar a los servicios web desde los flujos de trabajo, como se indica en la siguiente tabla. En los dos primeros ejemplos, los flujos de trabajo y las listas se implementan en la web del complemento cuando éste se instala. El último ejemplo proporciona el escudo básico de un flujo de trabajo e instrucciones sobre cómo implementarlo en la web host y asociarlo con una lista en la web host.

Tareas de flujo de trabajo y ejemplos asociados

Tarea Ejemplo
Llamar a servicios web personalizados desde un flujo de trabajo. Workflow.CallCustomService
Llame a un servicio web personalizado desde un flujo de trabajo y actualice SharePoint utilizando el proxy web de SharePoint. Workflow.CallServiceUpdateSPViaProxy
Asociar un flujo de trabajo con la web host. Workflow.AssociateToHostWeb

Llamada a servicios web personalizados desde un flujo de trabajo

El ejemplo Workflow.CallCustomService muestra cómo crear un flujo de trabajo que llame a un servicio web personalizado que actualice los datos de la lista de SharePoint. También muestra cómo diseñar un complemento alojado en un proveedor para que consulte un servicio web utilizando la aplicación web hospedada de forma remota que se implementa con el complemento. Este ejemplo es útil cuando se desea que todas las interacciones con el servicio web sean manejadas por la parte alojada de forma remota de su complemento alojado por el proveedor.

El ejemplo funciona iniciando un flujo de trabajo desde una aplicación web remota. Este flujo de trabajo pasa la información de la consulta enviada por el usuario a la aplicación web remota, que luego utiliza esa información para construir una consulta al servicio web OData de Northwind. La consulta devuelve los proveedores de productos de un país determinado. Tras recibir esa información, la aplicación web remota actualiza una lista de proveedores de productos que el complemento ha desplegado en la web del complemento.

Nota:

La página de ejemplo de Workflow.CallCustomService contiene instrucciones para implementar este complemento También puede implementar y probar con la depuración de F5 en Visual Studio si sigues las instrucciones de la entrada del blog Depuración de flujos de trabajo de SharePoint 2013 con Visual Studio 2013.

La página de inicio del complemento de ejemplo Workflow.CallCustomService incluye un menú desplegable en el que se puede seleccionar un país para el que se desea crear una lista de proveedores de productos.

Captura de pantalla que muestra la página de inicio del complemento de muestra


El botón Crear de la pantalla llama a un método Crear en el archivo Controllers\PartSuppliersController.cs que crea una nueva entrada en la lista de Proveedores de Piezas en la web del complemento. El método Crear llama al método Agregar que está definido en el archivo Services\PartSuppliersService.cs. La secuencia se muestra en los dos siguientes ejemplos de código.

Método Crear

public ActionResult Create(string country, string spHostUrl)
        {
            var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext);
            using (var clientContext = spContext.CreateUserClientContextForSPAppWeb())
            {
                var service = new PartSuppliersService(clientContext);
                var id = service.GetIdByCountry(country);
                if (id == null)
                {
                    id = service.Add(country);
                    TempData["Message"] = "Part Supplier Successfully Created!";
                }
                else
                    TempData["ErrorMessage"] = string.Format("Failed to Create The Part Supplier: There's already a Part Supplier who's country is {0}.", country);

                return RedirectToAction("Details", new { id = id.Value, SPHostUrl = spHostUrl });
            }
        }


Agregar método

public int Add(string country)
        {
            var item = list.AddItem(new ListItemCreationInformation());
            item["Country"] = country;
            item.Update();
            clientContext.ExecuteQuery();
            return item.Id;
        }


Después de crear ese nuevo elemento de la lista, el complemento presenta un botón paraIniciar flujo de trabajo que inicia el flujo de trabajo de aprobación.

Captura de pantalla que muestra la página de inicio del flujo de trabajo en el complemento de muestra


Al elegir el botón Iniciar flujo de trabajo se activa el método StartWorkflow que está definido en el archivo Controllers\PartSuppliersController.cs. (para su aplicación web alojada de forma remota, no para el servicio web de Northwind), y los valores del token de contexto, y los pasa al método StartWorkflow. El método PartSuppliersService necesita el token de contexto para interactuar con SharePoint.

public ActionResult StartWorkflow(int id, Guid workflowSubscriptionId, string spHostUrl)
        {
            var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext) as SharePointAcsContext;

            var webServiceUrl = Url.RouteUrl("DefaultApi", new { httproute = "", controller = "Data" }, Request.Url.Scheme);
            var payload = new Dictionary<string, object>
                {
                    { "appWebUrl", spContext.SPAppWebUrl.ToString() },
                    { "webServiceUrl", webServiceUrl },
                    { "contextToken",  spContext.ContextToken }
                };

            using (var clientContext = spContext.CreateUserClientContextForSPAppWeb())
            {
                var service = new PartSuppliersService(clientContext);
                service.StartWorkflow(workflowSubscriptionId, id, payload);
            }

            TempData["Message"] = "Workflow Successfully Started!";
            return RedirectToAction("Details", new { id = id, SPHostUrl = spHostUrl });
        }


El método StartWorkflow crea entonces una instancia de flujo de trabajo y pasa los tres valores (appWebUrl, webServiceUrl, contextToken) almacenados en la variable de carga útil al flujo de trabajo.

 {
            var workflowServicesManager = new WorkflowServicesManager(clientContext, clientContext.Web);

            var subscriptionService = workflowServicesManager.GetWorkflowSubscriptionService();
            var subscription = subscriptionService.GetSubscription(subscriptionId);

            var instanceService = workflowServicesManager.GetWorkflowInstanceService();
            instanceService.StartWorkflowOnListItem(subscription, itemId, payload);
            clientContext.ExecuteQuery();
        }


Después de que el flujo de trabajo se inicie, hace una petición POST HTTP a la aplicación web alojada de forma remota. Esta petición indica a la aplicación web que actualice la lista de proveedores con los proveedores del país que el usuario acaba de agregar. El archivo Controllers\DataController.cs contiene un métodoPOST que recibe el contenido de esta solicitud.

public void Post([FromBody]string country)
        {
            var supplierNames = GetSupplierNames(country);
            UpdateSuppliers(country, supplierNames);
        }


El método GetSupplierNames (en el archivo Controllers\DataController.cs) construye y ejecuta una consulta LINQ al servicio web OData de Northwind para todos los proveedores asociados al país seleccionado.

private string[] GetSupplierNames(string country)
        {
            Uri uri = new Uri("http://services.odata.org/V3/Northwind/Northwind.svc");
            var entities = new NorthwindEntities(uri);
            var names = entities.Suppliers
                .Where(s => s.Country == country)
                .AsEnumerable()
                .Select(s => s.CompanyName)
                .ToArray();
            return names;
        }


El método UpdateSuppliers actualiza el campo Proveedores del nuevo elemento de la lista.

private void UpdateSuppliers(string country, string[] supplierNames)
        {
            var request = HttpContext.Current.Request;
            var authority = request.Url.Authority;
            var spAppWebUrl = request.Headers["SPAppWebUrl"];
            var contextToken = request.Headers["SPContextToken"];

            using (var clientContext = TokenHelper.GetClientContextWithContextToken(
                spAppWebUrl, contextToken, authority))
            {
                var service = new PartSuppliersService(clientContext);
                service.UpdateSuppliers(country, supplierNames);
            }
        }


Si observa la vista de diseño del archivo workflow.xaml en el directorio Aprobar proveedores del proyecto del complemento, verá (eligiendo la pestaña Argumentos en la parte inferior izquierda de la vista de diseño) que el flujo de trabajo almacena los tres valores en la variable de carga útil que se le pasa como argumentos del flujo de trabajo.

Captura de pantalla que muestra la pantalla para especificar los argumentos de carga útil que se pasan al flujo de trabajo


La actividad HttpSend ocurre antes de la aprobación del flujo de trabajo. Esta actividad envía la consulta POST a su aplicación web remota que desencadena la llamada al servicio web de Northwind y luego a la actualización del elemento de la lista (con la lista de proveedores). Esta actividad está configurada para enviar la solicitud al valor de webServiceUrl que se pasó como argumento del flujo de trabajo.

Captura de pantalla que muestra el cuadro de texto para escribir la dirección URL del servicio web de envío HTTP


La solicitud POST también pasa el valor del país que se almacena en el elemento de la lista sobre el que opera el flujo de trabajo.

Captura de pantalla que muestra la cuadrícula de propiedades para la actividad de envío HTTP


El flujo de trabajo envía los valores appWebUrl y contextToken a la aplicación web a través de las encabezados de solicitud. Los encabezados también establecen los tipos de contenido para enviar y aceptar solicitudes.

Captura de pantalla que muestra la cuadrícula para agregar encabezados de solicitud de actividad de envío HTTP

Si el flujo de trabajo está aprobado, cambia el valor del campo isApproved del elemento de la lista a true.

Llamar a un servicio web personalizado desde un flujo de trabajo y actualizar SharePoint utilizando el proxy web de SharePoint

El ejemplo Workflow.CallServiceUpdateSPViaProxy muestra cómo diseñar un complemento alojado en un proveedor para consultar un servicio web y luego pasar esa información a una lista de SharePoint a través del proxy web de SharePoint.

El ejemplo muestra una tarea que es útil cuando se quiere encapsular todas las interacciones con un servicio web para que sean manejadas directamente por el flujo de trabajo. El uso del proxy web facilita la actualización de la lógica de la aplicación web remota sin tener que actualizar la instancia del flujo de trabajo. Si no está utilizando el proxy y tiene que actualizar la lógica en su aplicación web, debe eliminar las instancias de flujo de trabajo existentes y luego volver a implementar el complemento. Por esta razón, recomendamos este diseño cuando necesite llamar a un servicio web remoto.

Nota:

La página de ejemplo de Workflow.CallServiceUpdateSPViaProxy contiene instrucciones para implementar este complemento. También puede implementar y probar el complemento utilizando la depuración F5 en Visual Studio si sigue las instrucciones de la publicación del blog Depuración de flujos de trabajo de SharePoint 2013 con Visual Studio 2013.

El ejemplo inicia un flujo de trabajo desde una aplicación web remota. Este flujo de trabajo pasa la información de la consulta enviada por el usuario al servicio web OData de Northwind. La consulta devuelve los proveedores de productos de un país determinado. Después de recibir la respuesta del servicio web, el flujo de trabajo pasa la información de la respuesta a la aplicación web remota. La aplicación web remota actualiza entonces una lista de proveedores de productos que el complemento ha implementado en la web del complemento.

Cuando se inicia el complemento de ejemplo Workflow.CallServiceUpdateSPViaProxy, la página de inicio incluye un menú desplegable en el que se puede seleccionar el país para el que se desea crear una lista de proveedores de productos.

Captura de pantalla que muestra la página de inicio del complemento de muestra con la actualización del complemento de flujo de trabajo proxy


El botón Crear llama a un método en el archivo Controllers\PartSuppliersController.cs que crea una nueva entrada en la lista de Proveedores de piezas en la web del complemento. El método Crear de ese archivo llama al método Agregar que está definido en el archivo Services\PartSuppliersService.cs. Ambos se muestran en los siguientes dos ejemplos de código.

Método Crear

public ActionResult Create(string country, string spHostUrl)
        {
            var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext);
            using (var clientContext = spContext.CreateUserClientContextForSPAppWeb())
            {
                var service = new PartSuppliersService(clientContext);
                var id = service.GetIdByCountry(country);
                if (id == null)
                {
                    id = service.Add(country);
                    TempData["Message"] = "Part Supplier Successfully Created!";
                }
                else
                    TempData["ErrorMessage"] = string.Format("Failed to Create The Part Supplier: There's already a Part Supplier who's country is {0}.", country);

                return RedirectToAction("Details", new { id = id.Value, SPHostUrl = spHostUrl });
            }
        }


Agregar método

public int Add(string country)
        {
            var item = list.AddItem(new ListItemCreationInformation());
            item["Country"] = country;
            item.Update();
            clientContext.ExecuteQuery();
            return item.Id;
        }


Después de crear ese nuevo elemento de la lista, el complemento presenta un botón Iniciar flujo de trabajo que inicia el flujo de trabajo de aprobación.

Captura de pantalla que muestra la página Iniciar flujo de trabajo en el servicio web personalizado

Al elegir el botón Iniciar flujo de trabajo se activa el método StartWorkflow en el archivo Controllers\PartSuppliersController.cs. Este método empaqueta la URL web del complemento y la URL del servicio web (para su aplicación web alojada remotamente, no para el servicio web de Northwind) y las pasa al método StartWorkflow del archivo Services\PartSuppliersService.cs. El flujo de trabajo se comunica con la aplicación web remota a través del proxy web, y el proxy web agrega el token de acceso en un encabezado de solicitud. Por eso el flujo de trabajo no pasa un token de contexto al método StartWorkflow en este ejemplo. El código se muestra en el siguiente ejemplo.

public ActionResult StartWorkflow(int id, Guid workflowSubscriptionId, string spHostUrl)
        {
            var spContext = SharePointContextProvider.Current.GetSharePointContext(HttpContext);

            var webServiceUrl = Url.RouteUrl("DefaultApi", new { httproute = "", controller = "Data" }, Request.Url.Scheme);
            var payload = new Dictionary<string, object>
                {
                    { "appWebUrl", spContext.SPAppWebUrl.ToString() },
                    { "webServiceUrl", webServiceUrl }
                };

            using (var clientContext = spContext.CreateUserClientContextForSPAppWeb())
            {
                var service = new PartSuppliersService(clientContext);
                service.StartWorkflow(workflowSubscriptionId, id, payload);
            }

            TempData["Message"] = "Workflow Successfully Started!";
            return RedirectToAction("Details", new { id = id, SPHostUrl = spHostUrl });
        }


El método StartWorkflow crea una instancia de flujo de trabajo y pasa los dos valores (appWebUrl y webServiceUrl) almacenados en la variable de carga útil al flujo de trabajo.

public void StartWorkflow(Guid subscriptionId, int itemId, Dictionary<string, object> payload)
        {
            var workflowServicesManager = new WorkflowServicesManager(clientContext, clientContext.Web);

            var subscriptionService = workflowServicesManager.GetWorkflowSubscriptionService();
            var subscription = subscriptionService.GetSubscription(subscriptionId);

            var instanceService = workflowServicesManager.GetWorkflowInstanceService();
            instanceService.StartWorkflowOnListItem(subscription, itemId, payload);
            clientContext.ExecuteQuery();
        }


Después de que se inicie el flujo de trabajo, y antes de que se apruebe, el flujo de trabajo hace una consulta al servicio web de Northwind para recuperar la lista de proveedores del país que se ha seleccionado. Para ello, utiliza una actividad HTTPSend que envía una consulta OData a este punto de conexión: "http://services.odata.org/V3/Northwind/Northwind.svc/Suppliers/?$filter=Country eq '" + country.Replace("'", "''") + "'&amp;$select=CompanyName".

La actividad HttpSend debe configurarse como una petición GET con un encabezado Aceptar que especifica JSON sin metadatos: application/json;odata=nometadata.

Captura de pantalla que muestra la cuadrícula de la actividad de envío HTTP configurada como una solicitud GET

Captura de pantalla que muestra la cuadrícula Encabezados de solicitud para la actividad de envío HTTP


Si el usuario seleccionó Canadá para el nuevo elemento de la lista de proveedores, por ejemplo, la respuesta con formato JSON será como se muestra en el siguiente ejemplo.

{
    value: [
        {
            CompanyName: "Ma Maison"
        },
        {
            CompanyName: "Forêts d'érables"
        }
    ]
}


Después de que el flujo de trabajo se inicie, hace una petición POST HTTP que contiene la lista de proveedores a la aplicación web alojada remotamente a través del proxy. Lo hace a través de una actividad HttpSend que consulta la URL del proxy web: appWebUrl + "/_api/SP.WebProxy.invoke".

El flujo de trabajo pasa entonces la lista de proveedores que recibió del servicio Northwind compilando y pasando una carga útil de servicio personalizada. Las propiedades de la actividad Crear carga útil de servicio personalizada contienen la lista de proveedores y el ID del país proveedor.

Captura de pantalla que muestra las cuadrículas de propiedades y valores para una actividad de carga útil del servicio web personalizado


La actividad Crear carga útil de WebProxy construye una carga útil que pasa el contenido de esta carga útil a la URL del proxy web.

Captura de pantalla que muestra el cuadro de diálogo Crear actividad de carga útil de proxy web


Las propiedades de la actividad Carga útil de la WebProxy especifican la URL web del complemento, la longitud y el tipo de contenido de la solicitud POST y el tipo de aceptación de la solicitud a través de los encabezados de la solicitud.

Captura de pantalla que muestra la cuadrícula de propiedades para la actividad de carga útil de proxy web


Una vez que el flujo de trabajo ha construido la carga y la solicitud, pasa la solicitud al proxy web mediante una actividad HttpSend configurada como una solicitud POST a la dirección URL del proxy web. Los encabezados de la solicitud especifican OData con formato JSON en los encabezados Tipo de contenido y Aceptar.

Captura de pantalla que muestra el cuadro de diálogo Encabezados de solicitud para la actividad de envío HTTP


El método Post dentro del archivo Controllers\DataController.cs acepta el contenido de la solicitud que el flujo de trabajo envía a través del proxy web. El método Post del ejemplo anterior llamaba a un método para recuperar la lista de proveedores de Northwind, así como a otro para actualizar la correspondiente lista de proveedores de SharePoint.

Como el flujo de trabajo de este ejemplo ya ha consultado el servicio Northwind, esta versión del método sólo necesita actualizar la lista de SharePoint También pasa la URL web del complemento y el token de acceso (que pasa el proxy web) al método UUpdateSuppliers del archivo Services\PartSuppliersService.cs, como se muestra en el siguiente ejemplo de código.

public void Post(UpdatePartSupplierModel model)
        {
            var request = HttpContext.Current.Request;
            var authority = request.Url.Authority;
            var spAppWebUrl = request.Headers["SPAppWebUrl"];
            var accessToken = request.Headers["X-SP-AccessToken"];

            using (var clientContext = TokenHelper.GetClientContextWithContextToken(spAppWebUrl, accessToken, authority))
            {
                var service = new PartSuppliersService(clientContext);
                service.UpdateSuppliers(model.Id, model.Suppliers.Select(s => s.CompanyName));
            }
        }


El método UpdateSuppliers del archivo PartSuppliers.cs actualiza el campo Proveedores del elemento de la lista recién creado.

public void UpdateSuppliers(int id, IEnumerable<string> supplierNames)
        {
            var item = list.GetItemById(id);
            clientContext.Load(item);
            clientContext.ExecuteQuery();

            string commaSeparatedList = String.Join(",", supplierNames);
            item["Suppliers"] = commaSeparatedList;
            item.Update();
            clientContext.ExecuteQuery();
        }


Si el flujo de trabajo está aprobado, cambia el valor del campo isApproved del elemento de la lista a true.

Asociar un flujo de trabajo con la web host

El ejemplo Workflow.AssociateToHostWeb muestra cómo implementar un flujo de trabajo en la web host y asociarlo con una lista en la web host utilizando herramientas de Visual Studio. Las instrucciones de este ejemplo muestran cómo crear un flujo de trabajo en Visual Studio, implementarlo en la web host y asociarlo con una lista en la web host.

El ejemplo contiene un flujo de trabajo sencillo que puede asociarse a cualquier lista. Las instrucciones para implementar este flujo de trabajo muestran cómo sortear las limitaciones actuales de las herramientas de flujo de trabajo de Visual Studio empaquetando el complemento, abriéndolo y editando un archivo de configuración, y volviéndolo a empaquetar manualmente antes de implementarlo en la web host.

Cuando abra este proyecto en Visual Studio, verá que se trata de un flujo de trabajo sencillo y genérico, diseñado para funcionar con cualquier lista de SharePoint. Aparte de la lista de tareas del flujo de trabajo, no implementa ninguna lista a la que pueda asociarse.

Nota:

No puede realizar la tarea mostrada en este ejemplo utilizando Visual Studio 2013. Este ejemplo proporciona una solución útil. Si las herramientas de Visual Studio se actualizan en el futuro, es posible que no sea necesario utilizar esta solución.

Implementar un flujo de trabajo en la web host

  1. Abra el menú contextual (haga clic con el botón derecho) del proyecto del complemento Workflow.AssociateToHostWeb en el explorador de proyectos y seleccione Publicar. Verá una ventana que contiene un botón para Empaquetar la aplicación.

    Captura de pantalla que muestra la página Publicar la aplicación para publicar el complemento de ejemplo

  2. Al elegir Empaquetar la aplicación, Visual Studio crea un archivo Workflow.AssociateToHostWeb.app en el directorio de la bin\Debug\app.publish\1.0.0.0 solución. Este archivo .app es un tipo de archivo .zip.

  3. Extraiga el contenido del archivo cambiando primero la extensión del archivo a .zip.

  4. En el directorio que ha extraído, localice y abra el archivo XML llamado WorkflowManifest.xml. El archivo está vacío.

  5. Agregue el siguiente fragmento de XML al archivo, y luego guarde el archivo.

       <SPIntegratedWorkflow xmlns="http://schemas.microsoft.com/sharepoint/2014/app/integratedworkflow">
         <IntegratedApp>true</IntegratedApp>
       </SPIntegratedWorkflow>
    
  6. Seleccione todos los archivos de la carpeta extraída, y luego, abra el menú contextual (haga clic con el botón derecho) de los archivos y seleccione Enviar a la >Carpeta comprimida (zip).

  7. En el archivo zip que acaba de crear, cambie la extensión del archivo a .app. Ahora debería tener un nuevo paquete Workflow.AssociateToHostWeb.app que contiene el archivo WorkflowManifest.xml actualizado.

  8. Agregue el complemento al catálogo de aplicaciones.

  9. Instale el complemento en su sitio web.

  10. Vaya a una lista en su sitio de host y seleccione la opción de edición de la Lista en la parte superior izquierda de la página. Verá un menú desplegable de Configuración del flujo de trabajo.

    Captura de pantalla que muestra la configuración del flujo de trabajo para una lista

  11. Seleccione Agregar un flujo de trabajo en el menú desplegable.

  12. Ahora verá una opción de selección similar a la imagen de la siguiente figura. Seleccione el complemento Workflow.AssociateToHostWeb de la lista de opciones disponibles.

    Captura de pantalla que muestra la página de configuración Agregar un flujo de trabajo

Ahora ha implementado el flujo de trabajo en la web host y lo ha asociado con una lista en la web host. Puede activar un flujo de trabajo manualmente, o puede actualizar el flujo de trabajo en Visual Studio para que se active de otras maneras.

Consulte también