WorkFlow Sharepoint 2007- Formulario Aprobación ASPX

El último artículo que escribimos hablamos de cómo crear un formulario de asociación utilizando wss3workflow, herramienta que se puede descargar de CodePlex.

Cuando trabajamos con WorkFlow sobre Sharepoint tenemos que interactuar con el usuario para que el mismo tome una decisión en nuestro flujo de trabajo, casi siempre estas interacciones las codificamos en formularios Infopath y asociamos los mismo a nuestros flujos de trabajo. Bien, sabemos que desarrollar los formularios en Infopath es una tarea medianamente sencilla, dependerá de lo  complejo del mismo. Estos formularios nos permiten tomar las decisiones de los usuarios e informarle a nuestro flujo de trabajo la acción realizada por el usuario.

Pero estos formularios dependen de una característica de Moss, Forms Services, esta característica permite convertir el formulario Infopath en una simple pagina Web, con lo cual el usuario que esta interactuando con nuestro WorkFlow no necesita tener instalado Infopath en su máquina y así podemos tener nuestros preciados formularios cargados en el Internet Explorer.

Pero qué pasaría si nos encontramos en un ambiente diferente, supongamos que estamos desarrollando un componente de negocio para nuestro cliente, pero el mismo será montado sobre Windows Sharepoint Services y no sobre Moss, acá nuestro preciado formulario en Infopath no será del todo útil. Para este ambiente (WSS) deberemos codificar nuestros formularios en ASPX y asociarlos a nuestros flujos de trabajo, tarea que no es tan sencilla de realizar ni tan intuitiva como uno desearía, dado que deberemos codificar todo nosotros.

Pues bien acá es donde entra la herramienta wss3workflow , la cual nos brinda un template  para Visual Studio para crear formularios ASPX para nuestros flujos de trabajos.  En la imagen 1 se ve como se puede agregar un nuevo formulario de tarea a nuestro flujo de trabajo e insertarlo en nuestro proyecto.

 [Imagen 1]

1_VisualStudioTaskForm

 

Vale la pena aclarar que en esta artículo no vamos hablar de cómo crear un WorkFlow desde un principio, dado que eso lo hemos explicado en nuestro anterior artículo  WorkFlow de aprobación para Sharepoint 2007 paso a paso, lo que estaremos explicando en este artículo es como creamos un formulario ASPX de tarea.

En la imagen 2 vemos el WorkFlow creado para este ejemplo, el mismo es sencillo y cuenta con las actividades necesarias para la creación de una tarea dentro de Sharepoint 2007.

 

 [Imagen 2]

2_WorkFlow_Creado

 

Una vez que tenemos creado nuestro WorkFlow, lo próximo que vamos hacer es crear nuestro formulario ASPX, nos posicionamos arriba de nuestro proyecto (en mi caso coloque una carpeta en el mismo para centralizar los formularios) presionamos el botón derecho, agregar, nuevo elemento y nos tendría que aparecer una ventana similar a la mostrada en la imagen 1. Seleccionamos la plantilla TaskForm, le colocamos un nombre y presionamos el botón agregar.

Una vez completado el proceso se tuvieron que haber agregados dos archivos, un con extensión ASPX y otro con extensión ASPX.cs. Todos los que hemos trabajados con Asp.Net en algún momento conocemos bien estos dos archivos, uno contiene la declaración de nuestros controles y el otro el código asociado a los mismos.

Lo primero que vamos hacer es completar la directiva @Page del formulario Aspx para que el formulario quede correctamente asociado al código. Por defecto la directiva de pagina contiene el atributo “Inherits”, el cual indica cual es la clase que estará procesando toda la lógica de nuestro formulario, para ello simplemente agregamos una “,” inmediatamente después del nombre de la clase y agregamos toda la información de nuestro Assembly, para lo cual tendrán que firmarlo, compilar y generarlo, si todavía no lo hicieron.  En la sección 1 vemos como quedaría el atributo “Inherits” en la directiva de pagina @Page

 

 [Sección 1]

Inherits="Siderys.Blog.Workflow.Forms.ApprovalTaskFormWss, 
Siderys.Blog.Workflow.SimpleApprovalWorkFlowTaskForm, Version=1.0.0.0, 
Culture=neutral, PublicKeyToken=711eed342842acee " 

 

Bien una vez que modificamos dicho atributo, lo próximo que haremos en nuestro formulario ASPX es agregar el atributo “MasterPageFile” a la directiva de pagina @Page para indicar cuál será la Pagina Maestra que utilizaremos en el mismo. Esto es importante, dado que nuestro formulario solo cuenta con “PlaceHolder” para agregar el contenido y si no queremos obtener un error en tiempo de ejecución indicando  que no hay ninguna Pagina Maestra asociada debemos agregar este atributo como se muestra en la sección 2.

 

[Sección 2]

 

MasterPageFile="~/_layouts/application.master"

 

Para este ejemplo selecciona la Pagina Maestra llamada “application.master” debido a que quiero que aparezca todo el menú de navegación de Sharepoint en la parte superior, pero también podíamos haber elegido la Pagina Maestra “simple.master”.

Una vez realizada las modificaciones sobre la directiva de página, lo próximo que vamos a realizar es la construcción de nuestro formulario. En la sección 3 vemos el código Asp.Net de nuestro formulario ASPX diseñado para el WorkFlow, el solo contiene dos botones, una para aprobar y el otro para rechazar la tarea asignada al usuario.

 

[Sección 3]

 

 

<asp:Content ID=“_mainContentrunat=“serverContentPlaceHolderID=“PlaceHolderMain>

<spw:FormDigest ID=“_formDigestrunat=“server/>

<asp:Button ID=“btnApprovalTaskrunat=“serverText=“Aprobar Tarea
OnClick=“btnApprovalTask_Click/>

<asp:Button ID=“btnRechazarTarearunat=“serverText=“Rechazar Tarea
OnClick=“btnRechazarTarea_Click/>

</asp:Content>

 

Una vez creado nuestro formulario, lo próximo que haremos es agregar el código necesario en nuestra clase para programar los eventos de los dos botones.

Nosotros vamos agregar los manejadores de los dos botones (Aprobar y Rechazar) que están declarados en el formulario ASPX, como son manejadores para el evento Click su firma es sencilla. En el método que maneja el evento Click del botón aceptar vamos a invocar al método de nuestra clase base llamado “CommitTask()” y en el método que maneja el evento del botón Cancelar invocaremos al método “CancelTask()”.

Por último vamos a invocar la sobre cargar (override) del método OnPreRender implementado en nuestra clase base. Este método lo que realiza en la inserción de una serie de elementos ocultos en nuestro formulario donde se cargaran todos los datos asociados al WorkFlow.

Bien, ya hemos implementado nuestro formulario, en la sección 5 podemos ver el código completo.

 

[Sección 5]

using System;

using System.Collections;

using CodeCounsel.SharePoint.Workflow;

using Microsoft.SharePoint;

namespace Siderys.Blog.Workflow.Forms

{

    public partial class ApprovalTaskFormWss : TaskForm

    {

        protected override void OnPreRender(EventArgs e)

        {

            base.OnPreRender(e);

        }

        protected override void GetTaskCustomData(Hashtable container)

        {

            

        }

        protected void btnApprovalTask_Click(object sender, EventArgs e)

        {

            CommitTask();

        }

        protected void btnRechazarTarea_Click(object sender, EventArgs e)

        {

            CancelTask();

        }

    }

}

 

 

Para asociar nuestro formulario a la tarea lo que vamos a tener que hacer a través de un Content Type. Este Content Type estará relacionado con nuestro WorkFlow por intermedio de la propiedad “TaskListContentTypeId” del archivo WorkFlow.xml y que ahora estaremos viendo.

La única característica que tendrá este Content Type es la ruta a nuestro formulario ASPX, pero si tuviéramos que agregarles nuevas columnas o columnas del sitio lo podríamos hacer utilizando el elemento “<FieldRefs>” del Schema, donde podremos agregar todas las columnas que necesitemos.

Una vez insertado el nuevo archivo XML lo próximo que vamos hacer es colocar el elemento “Elements” y dentro de este elemento vamos a declarar el Content Type utilizando el elemento “ContentType”.  En la sección 6 vemos el código completo para la definición del Content Type y al archivo lo hemos llamado “TaskFormContentType.xml”, ahora veremos las propiedades que debemos configurar.

 

[Sección 6]

 

 

<Elements xmlns=”http://schemas.microsoft.com/sharepoint/ " >

 <ContentType ID=“0x01080100C5B9C785D13F43f38645772B1C5A152AName=“WorkFlowTaskAspxFormGroup=“Siderys.Blog.WorkflowDescription=“Task Form in Aspx FileVersion=“0Hidden=“FALSE>

<XmlDocuments>

<XmlDocument NamespaceURI=“ http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url”

&lt;FormUrls xmlns=“ http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url”

&lt;New>_layoutsSimpleApprovalFileFormsApprovalFormApprovalTaskFormWss.aspx</New>

<Display>_layoutsSimpleApprovalFileFormsApprovalFormApprovalTaskFormWss.aspx</Display>

 <Edit>_layoutsSimpleApprovalFileFormsApprovalFormApprovalTaskFormWss.aspx</Edit>

</FormUrls>

</XmlDocument>

</XmlDocuments>

</ContentType>

</Elements>

 

Lo primero que tenemos que hacer es establecerle un ID, este Id debe comenzar con el siguiente código 0x01080100 y después continuar con un Guid sin los “-“. Esto es un requisito muy importante dado que esta serie de números identifica al Content Type dentro de la herencia de Content Type de Sharepoint 2007 y lo marca como un Content Type para tareas de WorkFlow, en la siguiente pagina del MSDN podemos ver la jerarquía completa de los Content Type.

Lo cargamos un nombre para identificarlo,  indicamos el grupo donde queremos que se cargue dentro de los Content Types del sitio, una descripción, una versión e indicamos si el mismo estará visible.

Por último debemos indicar la ruta al formulario que creamos, para lo cual introducimos un elemento “XmlDocuments” y ahí establecemos la ruta para las opciones “New”, “Display” y “Edit”.

Lo próximo que vamos hacer es crear nuestro formulario WorkFlow.xml y lo vamos asociar al Content Type creado recientemente utilizando la propiedad “TaskListContentTypeId” como mencionamos.  No vamos a explicar este archivo en profundidad puesto que en artículos anteriores ya hemos profundizado en el mismo.  Entonces lo que debemos hacer una vez que el archivo fue creado, vamos a establecer el valor para la propiedad “TaskListContentTypeId” cargándole el ID del Content Type previamente creado. En la sección 7 vemos el código completo para nuestra definición del WorkFlow.xml.

 

[Sección 7]

 

<Elements xmlns=“ http://schemas.microsoft.com/sharepoint/”>

 <Workflow

Name=“Simple Approval WorkFlow Task Form AspxDescription=“Simple Approval WorkFlow Task Form AspxId=“4937ACF5-37DC-41b8-95AB-F2340DF6C2D1CodeBesideClass=“Siderys.Blog.Workflow.SimpleApprovalWorkFlowTaskFormCodeBesideAssembly=“Siderys.Blog.Workflow.SimpleApprovalWorkFlowTaskForm, Version=1.0.0.0, 
Culture=neutral, PublicKeyToken=711eed342842aceeStatusUrl=“_layouts/WrkStat.aspxTaskListContentTypeId=“0x01080100C5B9C785D13F43f38645772B1C5A152A> <Categories/> <MetaData> <StatusPageUrl>_layouts/WrkStat.aspx</StatusPageUrl> </MetaData> </Workflow> </Elements>

 

 Por último lo vamos a crear nuestro archivo Feature.xml donde estaremos declarando nuestro nuevo Feature para Sharepoint 2007 y estaremos agregando los dos archivos anteriormente construidos. En la sección 8 pueden ver cómo queda este archivo.

 

[Sección 8]

 <Feature  Id=“9DF221FB-20D8-4691-AAFD-DA6BF446FE2A

Title=“Simple Approval WorkFlow Task Form Aspx

Description=“Simple Approval WorkFlow Task Form Aspx

Version=“12.0.0.0

Scope=“Site

xmlns=“ http://schemas.microsoft.com/sharepoint/”>

<ElementManifests>

<ElementManifest Location=“TaskFormContentType.xml/>

<ElementManifest Location=“workflow.xml/>

</ElementManifests>

<Properties>

<Property Key=“GloballyAvailableValue=“true/>

WorkFlow Sharepoint 2007- Formulario Aprobación ASP X

El último artículo que escribimos hablamos de cómo crear un formulario de asociación utilizando wss3workflow, herramienta que se puede descargar de CodePlex.

Cuando trabajamos con WorkFlow sobre Sharepoint tenemos que interactuar con el usuario para que el mismo tome una decisión en nuestro flujo de trabajo, casi siempre estas interacciones las codificamos en formularios Infopath y asociamos los mismo a nuestros flujos de trabajo. Bien, sabemos que desarrollar los formularios en Infopath es una tarea medianamente sencilla, dependerá de lo  complejo del mismo. Estos formularios nos permiten tomar las decisiones de los usuarios e informarle a nuestro flujo de trabajo la acción realizada por el usuario. Pero estos formularios dependen de una característica de Moss, Forms Services, esta característica permite convertir el formulario Infopath en una simple pagina Web, con lo cual el usuario que esta interactuando con nuestro WorkFlow no necesita tener instalado Infopath en su máquina y así podemos tener nuestros preciados formularios cargados en el Internet Explorer. Pero qué pasaría si nos encontramos en un ambiente diferente, supongamos que estamos desarrollando un componente de negocio para nuestro cliente, pero el mismo será montado sobre Windows Sharepoint Services y no sobre Moss, acá nuestro preciado formulario en Infopath no será del todo útil. Para este ambiente (WSS) deberemos codificar nuestros formularios en ASPX y asociarlos a nuestros flujos de trabajo, tarea que no es tan sencilla de realizar ni tan intuitiva como uno desearía, dado que deberemos codificar todo nosotros. Pues bien acá es donde entra la herramienta wss3workflow , la cual nos brinda un template  para Visual Studio para crear formularios ASPX para nuestros flujos de trabajos.  En la imagen 1 se ve como se puede agregar un nuevo formulario de tarea a nuestro flujo de trabajo e insertarlo en nuestro proyecto.

 [Imagen 1]

1_VisualStudioTaskForm

 Vale la pena aclarar que en esta artículo no vamos hablar de cómo crear un WorkFlow desde un principio, dado que eso lo hemos explicado en nuestro anterior artículo  WorkFlow de aprobación para Sharepoint 2007 paso a paso, lo que estaremos explicando en este artículo es como creamos un formulario ASPX de tarea. En la imagen 2 vemos el WorkFlow creado para este ejemplo, el mismo es sencillo y cuenta con las actividades necesarias para la creación de una tarea dentro de Sharepoint 2007.  

 [Imagen 2]

2_WorkFlow_Creado 

Una vez que tenemos creado nuestro WorkFlow, lo próximo que vamos hacer es crear nuestro formulario ASPX, nos posicionamos arriba de nuestro proyecto (en mi caso coloque una carpeta en el mismo para centralizar los formularios) presionamos el botón derecho, agregar, nuevo elemento y nos tendría que aparecer una ventana similar a la mostrada en la imagen 1. Seleccionamos la plantilla TaskForm, le colocamos un nombre y presionamos el botón agregar. Una vez completado el proceso se tuvieron que haber agregados dos archivos, un con extensión ASPX y otro con extensión ASPX.cs. Todos los que hemos trabajados con Asp.Net en algún momento conocemos bien estos dos archivos, uno contiene la declaración de nuestros controles y el otro el código asociado a los mismos. Lo primero que vamos hacer es completar la directiva @Page del formulario Aspx para que el formulario quede correctamente asociado al código. Por defecto la directiva de pagina contiene el atributo “Inherits”, el cual indica cual es la clase que estará procesando toda la lógica de nuestro formulario, para ello simplemente agregamos una “,” inmediatamente después del nombre de la clase y agregamos toda la información de nuestro Assembly, para lo cual tendrán que firmarlo, compilar y generarlo, si todavía no lo hicieron.  En la sección 1 vemos como quedaría el atributo “Inherits” en la directiva de pagina @Page . 

 [Sección 1]

Inherits="Siderys.Blog.Workflow.Forms.ApprovalTaskFormWss,Siderys.Blog.Workflow.SimpleApprovalWorkFlowTaskForm, Version=1.0.0.0, Culture=neutral, PublicKeyToken=711eed342842acee"

Bien una vez que modificamos dicho atributo, lo próximo que haremos en nuestro formulario ASPX es agregar el atributo “MasterPageFile” a la directiva de pagina @Page para indicar cuál será la Pagina Maestra que utilizaremos en el mismo. Esto es importante, dado que nuestro formulario solo cuenta con “PlaceHolder” para agregar el contenido y si no queremos obtener un error en tiempo de ejecución indicando  que no hay ninguna Pagina Maestra asociada debemos agregar este atributo como se muestra en la sección 2. 

[Sección 2]

MasterPageFile="~/_layouts/application.master" 

Para este ejemplo selecciona la Pagina Maestra llamada “application.master” debido a que quiero que aparezca todo el menú de navegación de Sharepoint en la parte superior, pero también podíamos haber elegido la Pagina Maestra “simple.master”. Una vez realizada las modificaciones sobre la directiva de página, lo próximo que vamos a realizar es la construcción de nuestro formulario. En la sección 3 vemos el código Asp.Net de nuestro formulario ASPX diseñado para el WorkFlow, el solo contiene dos botones, una para aprobar y el otro para rechazar la tarea asignada al usuario.   

[Sección 3]

<asp:Content ID=“_mainContentrunat=“serverContentPlaceHolderID=“PlaceHolderMain>
<spw:FormDigest ID=“_formDigestrunat=“server/>
<asp:Button ID=“btnApprovalTaskrunat=“serverText=“Aprobar TareaOnClick=“btnApprovalTask_Click/>
<asp:Button ID=“btnRechazarTarearunat=“serverText=“Rechazar TareaOnClick=“btnRechazarTarea_Click/>
</asp:Content> 

Una vez creado nuestro formulario, lo próximo que haremos es agregar el código necesario en nuestra clase para programar los eventos de los dos botones.

Nosotros vamos agregar los manejadores de los dos botones (Aprobar y Rechazar) que están declarados en el formulario ASPX, como son manejadores para el evento Click su firma es sencilla. En el método que maneja el evento Click del botón aceptar vamos a invocar al método de nuestra clase base llamado “CommitTask()” y en el método que maneja el evento del botón Cancelar invocaremos al método “CancelTask()”. Por último vamos a invocar la sobre cargar (override) del método OnPreRender implementado en nuestra clase base. Este método lo que realiza en la inserción de una serie de elementos ocultos en nuestro formulario donde se cargaran todos los datos asociados al WorkFlow. Bien, ya hemos implementado nuestro formulario, en la sección 4 podemos ver el código completo.  

[Sección 4]

using System;

using System.Collections;

using CodeCounsel.SharePoint.Workflow;

using Microsoft.SharePoint;

namespace Siderys.Blog.Workflow.Forms

{

    public partial class ApprovalTaskFormWss : TaskForm

    {

        protected override void OnPreRender(EventArgs e)

        {

            base.OnPreRender(e);

        }

        protected override void GetTaskCustomData(Hashtable container)

        {

            

        }

        protected void btnApprovalTask_Click(object sender, EventArgs e)

        {

            CommitTask();

        }

        protected void btnRechazarTarea_Click(object sender, EventArgs e)

        {

            CancelTask();

        }

    }

}

Para asociar nuestro formulario a la tarea lo que vamos a tener que hacer a través de un Content Type. Este Content Type estará relacionado con nuestro WorkFlow por intermedio de la propiedad “TaskListContentTypeId” del archivo WorkFlow.xml y que ahora estaremos viendo. La única característica que tendrá este Content Type es la ruta a nuestro formulario ASPX, pero si tuviéramos que agregarles nuevas columnas o columnas del sitio lo podríamos hacer utilizando el elemento “<FieldRefs>” del Schema, donde podremos agregar todas las columnas que necesitemos. Una vez insertado el nuevo archivo XML lo próximo que vamos hacer es colocar el elemento “Elements” y dentro de este elemento vamos a declarar el Content Type utilizando el elemento “ContentType”.  En la sección 5 vemos el código completo para la definición del Content Type y al archivo lo hemos llamado “TaskFormContentType.xml”, ahora veremos las propiedades que debemos configurar.  

[Sección 5] 

<Elements xmlns=”http://schemas.microsoft.com/sharepoint/ " >
 <ContentType ID=“0x01080100C5B9C785D13F43f38645772B1C5A152AName=“WorkFlowTaskAspxFormGroup=“Siderys.Blog.WorkflowDescription=“Task Form in Aspx FileVersion=“0Hidden=“FALSE>

<XmlDocuments>

<XmlDocument NamespaceURI=“ http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url”

&lt;FormUrls xmlns=“ http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url”

&lt;New>_layoutsSimpleApprovalFileFormsApprovalFormApprovalTaskFormWss.aspx</New>

<Display>_layoutsSimpleApprovalFileFormsApprovalFormApprovalTaskFormWss.aspx</Display>

 <Edit>_layoutsSimpleApprovalFileFormsApprovalFormApprovalTaskFormWss.aspx</Edit>

</FormUrls>

</XmlDocument>

</XmlDocuments>

</ContentType>

</Elements> 

Lo primero que tenemos que hacer es establecerle un ID, este Id debe comenzar con el siguiente código 0x01080100 y después continuar con un Guid sin los “-“. Esto es un requisito muy importante dado que esta serie de números identifica al Content Type dentro de la herencia de Content Type de Sharepoint 2007 y lo marca como un Content Type para tareas de WorkFlow, en la siguiente pagina del MSDN podemos ver la jerarquía completa de los Content Type. Lo cargamos un nombre para identificarlo,  indicamos el grupo donde queremos que se cargue dentro de los Content Types del sitio, una descripción, una versión e indicamos si el mismo estará visible. Por último debemos indicar la ruta al formulario que creamos, para lo cual introducimos un elemento “XmlDocuments” y ahí establecemos la ruta para las opciones “New”, “Display” y “Edit”. Lo próximo que vamos hacer es crear nuestro formulario WorkFlow.xml y lo vamos asociar al Content Type creado recientemente utilizando la propiedad “TaskListContentTypeId” como mencionamos.  No vamos a explicar este archivo en profundidad puesto que en artículos anteriores ya hemos profundizado en el mismo.  Entonces lo que debemos hacer una vez que el archivo fue creado, vamos a establecer el valor para la propiedad “TaskListContentTypeId” cargándole el ID del Content Type previamente creado. En la sección 6 vemos el código completo para nuestra definición del WorkFlow.xml.  

[Sección 6] 

<Elements xmlns=“ http://schemas.microsoft.com/sharepoint/”>
 <Workflow
Name=“Simple Approval WorkFlow Task Form AspxDescription=“Simple Approval WorkFlow Task Form AspxId=“4937ACF5-37DC-41b8-95AB-F2340DF6C2D1CodeBesideClass=“Siderys.Blog.Workflow.SimpleApprovalWorkFlowTaskFormCodeBesideAssembly=“Siderys.Blog.Workflow.SimpleApprovalWorkFlowTaskForm,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=711eed342842aceeStatusUrl=“_layouts/WrkStat.aspxTaskListContentTypeId=“0x01080100C5B9C785D13F43f38645772B1C5A152A>

<Categories/>

<MetaData>

<StatusPageUrl>_layouts/WrkStat.aspx</StatusPageUrl>

</MetaData>

</Workflow>

  </Elements> 

 Por último lo vamos a crear nuestro archivo Feature.xml donde estaremos declarando nuestro nuevo Feature para Sharepoint 2007 y estaremos agregando los dos archivos anteriormente construidos. En la sección 7 pueden ver cómo queda este archivo.  

[Sección 7]

 <Feature  Id=“9DF221FB-20D8-4691-AAFD-DA6BF446FE2ATitle=“Simple Approval WorkFlow Task Form AspxDescription=“Simple Approval WorkFlow Task Form AspxVersion=“12.0.0.0Scope=“Sitexmlns=“ http://schemas.microsoft.com/sharepoint/”>

<ElementManifests>

<ElementManifest Location=“TaskFormContentType.xml/>

<ElementManifest Location=“workflow.xml/>

 </ElementManifests>

<Properties>

<Property Key=“GloballyAvailableValue=“true/>

</Properties>

</Feature> 

Una vez creado todos los archivos, lo que vamos hacer es instalar todo en Sharepoint 2007, para lo cual pueden utilizar el archivo .bat que se agrego a nuestro proyecto cuando creamos el mismo o bien pueden hacerlo a mano. En este caso nosotros vamos a utilizar el archivo .bat y el formulario lo vamos colocar en la carpeta _layouts de Sharepoint, para lo cual podemos modificar este archivo para que nos cree la carpeta necesaria y después nos copie los mismo. En la sección 8 pueden ver parte del archivo Install.bat y las modificaciones realizadas para que nos copie el archivo ASPX.

[Sección 8] 

echo Copying the feature... 
 rd /s /q "%programfiles%Common FilesMicrosoft Sharedweb server extensions12 TEMPLATEFEATURESSimpleApprovalWorkFlowTaskForm" 
 mkdir "%programfiles%Common FilesMicrosoft Sharedweb server extensions12 TEMPLATEFEATURESSimpleApprovalWorkFlowTaskForm" 
 mkdir "%programfiles%Common FilesMicrosoft Sharedweb server extensions12 TEMPLATELAYOUTSSimpleApprovalFileFormsApprovalForm" 
 copy /Y feature.xml  "%programfiles%Common FilesMicrosoft Sharedweb server extensions12TEMPLATEFEATURESSimpleApprovalWorkFlowTaskForm" 
 copy /Y workflow.xml  "%programfiles%Common FilesMicrosoft Sharedweb server extensions12 TEMPLATEFEATURESSimpleApprovalWorkFlowTaskForm" 
 copy /Y TaskFormContentType.xml  "%programfiles%Common FilesMicrosoft Sharedweb server extensions12 TEMPLATEFEATURESSimpleApprovalWorkFlowTaskForm" 
 copy /Y Forms*.aspx "%programfiles%Common FilesMicrosoft Sharedweb server extensions12 TEMPLATELAYOUTSSimpleApprovalFileFormsApprovalForm" 

  Una vez instalado, lo que vamos hacer es activar nuestro Feature en Sharepoint, si el mismo esta instaldo, desactívenlo y actívenlo de nuevo, para asegurarse que el Content Type se cree correctamente. En la imagen 3 vemos la lista de Feature y nuestro Feature activado nuevamente.

[Imagen 3]

  3_Features_Sharepoint

Si accedemos a los Content Type el sitio podremos ver nuestro Content Type creado, en la imagen 4 vemos la lista de Content Type del sitio.  

[Imagen 4]

   4_Content_Types

En la imagen 5 podremos ver la tarea asignada al usario.  

[Imagen 5]

   5_Tarea_Asignada

En la imagen 6 podemos ver nuestro formulario cargado una vez que el usuario selecciono la tarea asignada.  

[Imagen 6]

   6_Formulario_Task_Aspx

Por último en la imagen 7 vemos la tarea completada por el usuario.  

[Imagen 7]

   7_Tarea_Completada

En el próximo artículo esteremos hablando de cómo se manejan las excepciones en nuestros WorkFlow y nos esteramos adentrando en algunas actividades específicas.

WorkFlow Sharepoint 2007 – Formulario de asociación ASPX

Se pensaron que nos habíamos ido, no estamos acá nuevamente, después de pasar un mes de Marzo bastante movido en lo referente a trabajo y en lo personal con algunas complicaciones que por suerte superamos, nos hicimos hueco para retomar nuestro blog y escribir este artículo.

El último artículo que escribimos hablamos de cómo hacer un “WorkFlow de aprobación para Sharepoint 2007 paso a paso” donde hablamos del ambiente que necesitamos y describimos paso a paso la creación de un WorkFlow para Sharepoint utilizando Visual Studio. Este WorkFlow utilizaba un formulario creado con Infopath 2007 para la aprobación de tareas, el cual nos simplifica mucho utilizar Infopath para crear formularios para interactuar con los usuarios.

Después de publicar este artículo y someterlo a la crítica de mi buen amigo Haaron Gonzalez (gracias Haaron por tus palabras de aliento para que siga escribiendo, como ves sigoJ) el cual paso con buenas calificaciones, me puse a trabajar en la creación de un WorkFlow también para Sharepoint 2007, pero esta vez utilizando formularios ASPX de  Asp.Net y no formularios construidos con Infopath 2007. Hablando con Haaron, me comento que existía una herramienta, wss3workflow, publicada en CodePlex, que permitía crear formularios ASPX para nuestros WorkFlow sin la necesidad de hacerlo todo a pulmón. Esta herramienta, una vez instalada, nos brinda una serie de plantillas en el Visual Studio para agregar formularios,  cuando seleccionamos agregar un nuevo elemento en nuestro proyecto. Para este proyecto, yo me cree una carpeta llamada “AssociationForm” para colocar el formulario de asociación que vamos a estar creando, parados en la carpeta presionamos el botón derecho, agregar, nuevo elemento y nos despliega una nueva ventana como se puede ver en la imagen 1, donde seleccionaremos “Association Form”, colocaremos un nombre y presionamos agregar.

Imagen 1

 1_AsosiationForm_VS

Vale la pena aclarar que en esta artículo no vamos hablar de cómo crear un WorkFlow desde un principio, dado que eso lo hemos explicado en nuestro anterior artículo  WorkFlow de aprobación para Sharepoint 2007 paso a paso, lo que estaremos explicando en este artículo es como creamos un formulario ASPX de asociación y en el próximo artículo vernos como crear un formulario de tarea.

El formulario de asociación nos sirve para cargar información adicional a nuestro WorkFlow cuando el mismo está siendo asociado a la lista. En este ejemplo en concreto lo que estamos haciendo es indicar que persona será la encargada de aprobar la tarea que se está creando, a lo cual nos permite indicar quienes son los aprobadores y tener un WorkFlow de aprobación genérico.

En la imagen 2 vemos el WorkFlow que hemos creado, es un WorkFlow sencillo puesto que lo que queríamos compartir con Uds era la utilización de los formularios.

Imagen 2

 2_WorkFlow_Creado

Una vez que tenemos creado nuestro WorkFlow, lo que debemos hacer es programar nuestro formulario. Cuando agregamos el formulario a nuestro proyecto, en el mismo se agregaron dos archivos, el archivo ASPX y el archivo Aspx.cs el cual tendrá todo nuestro código servidor.

Lo primero que vamos hacer es completar la directiva @Page del formulario Aspx para que el formulario quede correctamente asociado al código. Por defecto la directiva de pagina contiene el atributo “Inherits”, el cual indica cual es la clase que estará procesando toda la lógica de nuestro formulario, pero con esto solo no basta, si estuviéramos bajo el contexto de una aplicación normal de Asp.Net donde nuestro archivo cs queda asociado al formulario no tendríamos problemas, pero acá el contexto es un poco diferente, dado que la clase que hace de Code Beheind se encuentra en el mismo Assembly generado para nuestro WorkFlow, así que lo que vamos hacer es agregarle a nuestro atributo “Inherits” cuál es el Assembly que contiene la clase que se tienen que invocar cuando el formulario sea cargado, para ello simplemente agregamos una “,” inmediatamente después del nombre de la clase y agregamos toda la información de nuestro Assembly, para lo cual tendrán que firmarlo, compilar y generarlo, si todavía no lo hicieron.  En la sección 1 vemos como quedaría el atributo “Inherits” en la directiva de pagina @Page.


Sección 1

Inherits="Siderys.Blog.Workflow.WorkShop.AssociationForm.AssociationFormSimpleApprovalWF, Siderys.Blog.Workflow.WorkShop.SimpleApprovalWorkflowAssosiationForm, Version=1.0.0.0, Culture=neutral, PublicKeyToken=711eed342842acee"

 

Bien una vez que modificamos dicho atributo, lo próximo que haremos en nuestro formulario ASPX es agregar el atributo “MasterPageFile” a la directiva de pagina @Page para indicar cuál será la Pagina Maestra que utilizaremos en el mismo. Esto es importante, dado que nuestro formulario solo cuenta con “PlaceHolder” para agregar el contenido y si no queremos obtener un error en tiempo de ejecución indicando  que no hay ninguna Pagina Maestra asociada debemos agregar este atributo como se muestra en la sección 2.

 

Sección 2

MasterPageFile="~/_layouts/application.master"

 

Para este ejemplo selecciona la Pagina Maestra llamada “application.master” debido a que quiero que aparezca todo el menú de navegación de Sharepoint en la parte superior, pero también podíamos haber elegido la Pagina Maestra “simple.master”.

 

Una vez realizada las modificaciones sobre la directiva de página, lo próximo que vamos a realizar es la construcción de nuestro formulario. El formulario que vamos a crear es sencillo, contendrá un Asp.Net TextBox , dos Button y un RequiredFieldValidator. La caja de texto se utilizara para cargar el usuario a quien se le asignara la tarea de aprobación, en este ejemplo utilizamos una simple caja de texto, pero podríamos haber utilizado el control de Sharepoint PeopleEditor, para seleccionar usuarios. En el artículo “Como usar el  control PeopleEditor de Sharepoint 2007” encontraran como utilizar fácilmente.
En la sección 3 vemos el código Asp.Net de nuestro formulario ASPX diseñado para el WorkFlow.

 

Sección 3

<%@ Page Language="C#" MasterPageFile="~/_layouts/application.master" 
Inherits="Siderys.Blog.Workflow.WorkShop.AssociationForm.AssociationFormSimpleApprovalWF, 
Siderys.Blog.Workflow.WorkShop.SimpleApprovalWorkflowAssosiationForm, Version=1.0.0.0, 
Culture=neutral, PublicKeyToken=711eed342842acee" %>
                                                                                                                 
<%@ Register TagPrefix="spw" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, 
PublicKeyToken=71e9bce111e9429c" Namespace="Microsoft.SharePoint.WebControls" %>
<%@ Register TagPrefix="spu" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" Namespace="Microsoft.SharePoint.Utilities" %>
<asp:Content ID="Content1" ContentPlaceHolderId="PlaceHolderPageTitle" runat="server"> <span>Simple Approval Workflow Association Forms</span> </asp:Content> <asp:Content ID="Content2" contentplaceholderid="PlaceHolderPageTitleInTitleArea" runat="server"> <asp:Label runat="server" ID="Label1" Text="Simple Approval Workflow Association Forms" /> </asp:Content> <asp:Content id="_mainContent" runat="server" ContentPlaceHolderId="PlaceHolderMain" > <table> <tr> <td> <asp:Label id="lblApprovador" runat="server" /> </td> <td> <asp:TextBox id="txtApprovador" runat="server" /> <asp:RequiredFieldValidator ID="rfvApprovador" runat="server"
ControlToValidate="txtApprovador">*</asp:RequiredFieldValidator> </td> </tr> <tr> <td> <asp:Button id="btnAceptar" runat="server" text="Aceptar" OnClick="btnAceptar_Click" /> </td> <td> <asp:Button id="btnCancel" runat="server" text="Cancel" OnClick="btnCancel_Click" /> </td> </tr> </table> <spw:FormDigest ID="_formDigest" runat="server" /> </asp:Content>

Una vez creado nuestro formulario, lo próximo que haremos es agregar el código necesario en nuestra clase para programar los eventos de los dos botones y cargar la información introducida por el usuario para ser enviada al WorkFlow. Cuando creamos el formulario se creó esta clase asociada al mismo, la cual extiende de la clase “AssociationForm” que se encuentra en el Assembly  “CodeCounsel.SharePoint.Workflow.dll” instalado cuando instalamos el Add-In para el Visual Studio y que se encuentra en la GAC.  

Al abrir esta clase nos encontramos que la misma tiene un constructor por defecto y la sobrecarga del método GetAssocationCustomData(). Este método es el utilizado por el formulario para enviar la información al WorkFlow una vez asociado. Este método, solo nos permite enviar un String, pero podríamos crear un objeto complejo, serializarlo a XML y envíalo como un String al WorkFlow, a lo cual lo único que deberíamos hacer en el WorkFlow es tomar dicha información y nuevamente convertirla en nuestro Objeto complejo para tomar sus valores, de misma forma que  Infopath interactúa con el WorkFlow.

Nosotros vamos agregar los manejadores de los dos botones (Aceptar y Cancelar) que están declarados en el formulario ASPX, como son manejadores para el evento Click su firma es sencilla. En el método que maneja el evento Click del botón aceptar vamos a invocar al método de nuestra clase base llamado “CommitAssocation()” el cual terminara de asociar toda la información al WorkFlow. Este método esta declarado en la clase “AssociationForm” y lo que hace es realizar la asociación del WorkFlow a la lista correspondiente y en el método que maneja el evento del botón Cancelar invocaremos al método “CancelAssociation()” que redirecciona al usuario nuevamente a la página de propiedades de la lista. En la imagen 3 vemos el código del método “”, para lo cual inspeccionamos el Assembly utilizando la herramienta Reflector.

Imagen 3

3_Reflector 

Por último vamos a invocar la sobre cargar (override) del método OnPreRender implementado en nuestra clase base. Este método lo que realiza en la inserción de una serie de elementos ocultos en nuestro formulario donde se cargaran todos los datos asociados al WorkFlow, guid de la lista, nombre del WorkFlow,  Id de la lista de tareas, etc. Esta información nos podría ser de utilidad por si queremos realizar alguna tarea previa a la asociación del WorkFlow. En la imagen 4 vemos el código de este método implementado en nuestra clase base.

Imagen 4

4_OnPreRender 

Bien, ya hemos implementado nuestro formulario, en la sección 5 podemos ver el código completo.

Sección 5

using System;

using CodeCounsel.SharePoint.Workflow;

using System.Web.UI.WebControls;

 

namespace Siderys.Blog.Workflow.WorkShop.AssociationForm

{

    public partial class AssociationFormSimpleApprovalWF : CodeCounsel.SharePoint.Workflow.AssociationForm

    {

        protected TextBox txtApprovador;

        protected override void OnPreRender(EventArgs e)

        {

            base.OnPreRender(e);

        }

 

        protected override string GetAssocationCustomData()

        {

            return txtApprovador.Text;

        }

 

        protected void btnAceptar_Click(object sender, EventArgs e)

        {

             CommitAssocation();

        }

        protected void btnCancel_Click(object sender, EventArgs e)

        {

            CancelAssociation();

        }

    }

}

 

Por último lo que debemos hacer es modificar el archivo WorkFlow.xml, para relacionar nuestro formulario con el WorkFlow, para ello utilizaremos el atributo “AssociationUrl” de elemento “Workflow” dentro del archivo xml. El formulario en nustro caso fue colocado bajo la ruta de “layout” de Sharepoint para el mismo sea tenido en cuenta desde cualquier sitio de nuestro portal Sharepoint. En la sección 6 vemos el código completo del archivo WorkFlow.xml .

Sección 6

  <Workflow
     Name="SimpleApprovalWorkflow Asociation Forms"
     Description="SimpleApprovalWorkflow Asociation Forms"
     Id="737F046D-8715-4803-811E-111EDAF2F65D"
     CodeBesideClass="Siderys.Blog.Workflow.WorkShop.SimpleApprovalWorkflowAssosiationForm"
     CodeBesideAssembly="Siderys.Blog.Workflow.WorkShop.SimpleApprovalWorkflowAssosiationForm, 
Version=1.0.0.0, Culture=neutral, PublicKeyToken=711eed342842acee"
AssociationUrl="_layoutsSimpleApprovalFileFormsAssociationFormAssociationFormSimpleApprovalWF.aspx"> <Categories/> <MetaData> <StatusPageUrl>_layouts/WrkStat.aspx</StatusPageUrl> </MetaData> </Workflow> </Elements>

Lo que nos resta es tomar la información cargada en nuestro formulario dentro del WorkFlow, para lo cual utilizando la propiedad “AssociationData” que se encuentra dentro de las WorkflowProperties podemos acceder a la información introducida en nuestro formulario. En la sección 7 vemos el código del evento “Invoked” que se dispara cuando se inicia el WorkFlow.

 

Sección 7

        private void onWorkflowActivated_Invoked(object sender, ExternalDataEventArgs e)

        {

            mUserApprover = onWorkflowActivated_WorkflowProperties.AssociationData;

        }

En la imagen 5 podemos ver nuestro formulario en ejecución cuando estamos asociando un WorkFlow

 

Imagen 5

 5_AsosciadonForm_Ejecucion

En próximos artículos seguiremos mostrando como utilizar este Add-In en nuestros WorkFlow y vamos a estar empezando a trabajar sobre la plataforma 2008 con Sharepoint 2007 y así ver las ventajas que se han introducido en el nuevo Visual Studio para trabajar con Sharepoint.