SharePoint 2010 & Office 365: Como asociar un workflow declarativo a una lista de un sitio (I)!

Hace un tiempo escribía sobre como podemos iniciar de forma sencilla un flujo de trabajo desde un manejador de eventos. En aquel ejemplo en concreto, el código permitía asociar un flujo de trabajo de sitio en base al GUID de la plantilla del workflow ya desplegada…pero, ¿y qué pasa si estamos ante un flujo de tipo declarativo (válido por tanto para SharePoint 2010 On-Premise como para SharePoint Online en Office 365)? ¿Cómo lo asociamos a una lista existente? Lógicamente, la aproximación que seguí en aquel caso me sirve para flujos declarativos que modelemos en SharePoint Designer 2010 (SPD 2010) y luego importemos en Visual Studio 2010 para facilitar el empaquetado y despliegue de los mismos como soluciones SandBox. Bueno, el caso es que tras un poco de pelea encontré la forma de asociar un flujo de trabajo a una lista de un sitio existente usando en este caso un Feature Event Receiver de acuerdo al siguiente código:

   1: using System;

   2: using System.Runtime.InteropServices;

   3: using System.Security.Permissions;

   4: using Microsoft.SharePoint;

   5: using Microsoft.SharePoint.Security;

   6:  

   7: //Espacios de nombres necesarios

   8: using Microsoft.SharePoint.Workflow;

   9: using System.Globalization;

  10:  

  11: namespace ComasisReusableWFv2.Features.Feature1

  12: {

  13:     /// <summary>

  14:     /// Clase que permite extender SPWeb

  15:     /// </summary>

  16:     public static class SPWebExtensions

  17:     {

  18:         public static bool ListExists(this SPWeb web, string listName)

  19:         {

  20:             var lists = web.Lists;

  21:             foreach (SPList list in lists)

  22:             {

  23:                 if (list.Title.Equals(listName))

  24:                     return true;

  25:             }

  26:             return false;

  27:         }

  28:     }

  29:  

  30:     /// <summary>

  31:     /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.

  32:     /// </summary>

  33:     /// <remarks>

  34:     /// The GUID attached to this class may be used during packaging and should not be modified.

  35:     /// </remarks>

  36:  

  37:     [Guid("655c2fac-732f-4227-a7eb-ea784d846614")]

  38:     public class Feature1EventReceiver : SPFeatureReceiver

  39:     {        

  40:         // Uncomment the method below to handle the event raised after a feature has been activated.

  41:  

  42:         public override void FeatureActivated(SPFeatureReceiverProperties properties)

  43:         {

  44:             SPWeb spwWeb = (SPWeb)properties.Feature.Parent;

  45:             //Comprobamos si la lista anuncios existe

  46:             if (spwWeb.ListExists("Anuncios"))

  47:             {

  48:                 SPList splList = spwWeb.Lists["Anuncios"];

  49:                 //Eliminamos lista de tareas

  50:                 if (spwWeb.ListExists("Lista tareas workflow declarativo"))

  51:                 {

  52:                     spwWeb.Lists["Lista tareas workflow declarativo"].Delete();

  53:                 }

  54:  

  55:                 //Eliminamos lista de historial

  56:                 if (spwWeb.ListExists("Lista historial workflow declarativo"))

  57:                 {

  58:                     spwWeb.Lists["Lista historial workflow declarativo"].Delete();

  59:                 }

  60:                 Guid taskListID = spwWeb.Lists.Add(

  61:                         "Lista tareas workflow declarativo", "",

  62:                         SPListTemplateType.Tasks);

  63:                 Guid historyListID = spwWeb.Lists.Add(

  64:                         "Lista historial workflow declarativo", "",

  65:                         SPListTemplateType.WorkflowHistory);

  66:  

  67:                 SPWorkflowTemplate spwtTemplate =

  68:                     spwWeb.WorkflowTemplates.GetTemplateByName("CopiarElemento",

  69:                     new CultureInfo

  70:                         (Convert.ToInt32(spwWeb.RegionalSettings.LocaleId)));

  71:                 SPWorkflowAssociation spwaWorkflowAssociation =

  72:                  SPWorkflowAssociation.CreateListAssociation(spwtTemplate,

  73:                     "Copiar elemento",

  74:                 spwWeb.Lists[taskListID],

  75:                 spwWeb.Lists[historyListID]);

  76:                 splList.WorkflowAssociations.Add(spwaWorkflowAssociation);

  77:             }

  78:  

  79:         }

  80:  

  81:  

  82:         // Uncomment the method below to handle the event raised before a feature is deactivated.

  83:  

  84:         //public override void FeatureDeactivating(SPFeatureReceiverProperties properties)

  85:         //{

  86:         //}

  87:  

  88:  

  89:         // Uncomment the method below to handle the event raised after a feature has been installed.

  90:  

  91:         //public override void FeatureInstalled(SPFeatureReceiverProperties properties)

  92:         //{

  93:         //}

  94:  

  95:  

  96:         // Uncomment the method below to handle the event raised before a feature is uninstalled.

  97:  

  98:         //public override void FeatureUninstalling(SPFeatureReceiverProperties properties)

  99:         //{

 100:         //}

 101:  

 102:         // Uncomment the method below to handle the event raised when a feature is upgrading.

 103:  

 104:         //public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)

 105:         //{

 106:         //}

 107:     }

 108: }

Cómo vemos, lo que tenemos que hacer es:

  • En primer lugar, crearnos un objeto de tipo SPWeb a partir del objeto properties del feature receiver que es de tipo SPFeatureREceiverProperties.
  • A continuación, gracias al correspondiente método de extensión comprobamos que la lista a la que queremos añadirle el workflow existe.
  • Añadimos las listas de tareas e historail que necesita el flujo de trabajo.
  • Definimos un objeto de tipo SPWorkflowTemplate a partir del nombre de la plantilla del flujo de trabajo tal y como la creamos y guardamos en SPD 2010.
  • Definimos un objeto de tipo SPWorkflowAssociation a patir del método CreateListAssociation que recibe la plantilla de workflow, el nombre de la instancia del workflow, la lista de tareas y la lista de historial.
  • Añadimos el objeto de tipo SPWorkflowAssociation a la lista y listo.

Hacemos el despliegue de nuestra solución y comprobamos:

  • Qué el workflow ha sido asociado correctamente a la lista.
  • Se ha creado la lista de tareas vinculada al flujo.
  • Se ha creado la lista de historial vinculada al flujo (en este caso la podremos ver desde SPD 2010 ya que es una lista oculta).
image image image

Y hasta aquí llega este post sobre como asociar un workflow declarativo a una lista existente de un sitio, ya sea para SharePoint 2010 On-Premise o para SharePoint Online en Office 365.

Publicado por

Juan Carlos González

Juan Carlos es Ingeniero de Telecomunicaciones por la Universidad de Valladolid y Diplomado en Ciencias Empresariales por la Universidad Oberta de Catalunya (UOC). Cuenta con más de 12 años de experiencia en tecnologías y plataformas de Microsoft diversas (SQL Server, Visual Studio, .NET Framework, etc.), aunque su trabajo diario gira en torno a SharePoint & Office 365. Juan Carlos es MVP de Office Servers & Services desde 2015 (anteriormente fue reconocido por Microsoft como MVP de Office 365 y MVP de SharePoint Server desde 2008 hasta 2015), coordinador del grupo de usuarios .NET de Cantabria (Nuberos.Net, www.nuberos.es), co-fundador y coordinador del Grupo de Usuarios de SharePoint de España (SUGES, www.suges.es), así como co-director de la revista gratuita en castellano sobre SharePoint CompartiMOSS (www.compartimoss.com). Hasta la fecha, ha publicado 8 libros sobre SharePoint & Office 365 y varios artículos en castellano y en inglés sobre ambas plataformas.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *