In questo articolo viene descritta la procedura per la creazione di un WorkFlow, il quale rileva e visualizza nel dettaglio del Workflow, il valore situato in una casella di testo di una pagina Asp.net.
Vedremo come utilizzare un workflow creato con Windows Workflow Foundation, da utilizzare in una pagina Aspx in Sharepoint 2007.
Creazione del progetto e progettazione Workflow
Da Visual Studio 2005 si crea un nuovo progetto di tipo sharepoint, selezionare il modello “Sharepoint Server Sequential Workflow Library”.
Il workflow sarà composto di un solo nuovo elemento e precisamente del controllo logToHistoryListActivity, tale controllo visualizzare a fine esecuzione del workflow il dato immesso nella casella di testo.
Il Workflow dovrà avere l’aspetto simile a quello della figura 1.
Figura 1
Per il controllo logToHistoryListACtivity, impostiamo la proprietà HistoryDescription, con un campo denominato (dalla finestra di questa proprietà, selezionare il tab “Bind To a new member”, opzione create Field ) HistoryDescription .
Mentre per la proprietà HistoryOutCome, impostiamo il seguente valore (di tipo field) HistoryOutcome
Fatto ciò aggiungiamo un metodo per l’evento MethodInvoking, in questo evento, visualizzeremo il testo che verrà riportato nel dettaglio del workflow, in particolare nella sezione “Cronologia flusso di lavoro”.
Il codice di tale operazioni è il seguente:
VB.Net
Private Sub logAttivita_MethodInvoking(ByVal sender As System.Object, ByVal e As System.EventArgs)
HistoryDescription = "Valore passato: " & workflowProperties.InitiationData
HistoryOutcome = "Workflow Terminato"
End Sub
C#
private void logAttivita_MethodInvoking(object sender, EventArgs e)
{
HistoryDescription = "Valore Passato: " + workflowProperties.InitiationData;
HistoryOutcome = "Workflow Terminato";
}
Creazione dei file XM:
Terminata la fase per di modellazione del nostro workflow, non ci resta che impostare i file di configurazioni, quali feature.xml e workflow.xml, creati di default nel progetto, nel momento in cui si crea un nuovo progetto di Sharepoint.
Selezionare il file Feature.xml, inseriamo il code snippet denominato Feature.xml (Snippets->SharePoint Workflow).
Di seguito si riporta il file Feature.xml, completato in ogni sua parte.
<?xmlversion="1.0"encoding="utf-8"?>
<!-- _lcid="1033" _version="12.0.3111" _dal="1" -->
<!-- _LocalBinding -->
<!-- Insert Feature.xml Code Snippet here. To do this:
1) Right click on this page and select "Insert Snippet" (or press Ctrl+K, then X)
2) Select Snippets->SharePoint Workflow->Feature.xml Code -->
<Feature Id="3A61C8FC-0986-443c-B9CF-DA5F187E09C8"
Title="Rileva Valori"
Description="questo Workflow rileva il valore di una casella di testo e lo visualizza a video"
Version="12.0.0.0"
Scope="Site"
ReceiverAssembly="Microsoft.Office.Workflow.Feature, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
ReceiverClass="Microsoft.Office.Workflow.Feature.WorkflowFeatureReceiver"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifestLocation="workflow.xml" />
</ElementManifests>
<Properties>
<PropertyKey="GloballyAvailable"Value="true" />
</Properties>
</Feature>
Terminata la fase di compilazione del file Feature.xml non ci resta che completare il file Workflow.xml.
Anche in questo caso, una volta selezionato il file Workflow.xml, inseriamo il code snippet, denominato Workflow.xml (Snippets->SharePoint Workflow).
Di seguito si riporta il file workflow.xml, completo in ogni sua parte, da ricordare che l’attributo publickeytoken si ottiene registrando la dll nella gac, la quale dll dev’essere compilata con una firma sicura.
File Workflow.xml
<?xmlversion="1.0"encoding="utf-8" ?>
<!-- _lcid="1033" _version="12.0.3015" _dal="1" -->
<!-- _LocalBinding -->
<!-- Insert Workflow.xml Code Snippet here. To do this:
1) Right click on this page and select "Insert Snippet" (or press Ctrl+K, then X)
2) Select Snippets->SharePoint Workflow->Workflow.xml Code -->
<Elementsxmlns="http://schemas.microsoft.com/sharepoint/">
<Workflow
Name="Rileva Valore"
Description="Il Workflow visualizza il valore di una casella di testo di una pagina"
Id="E96182E2-8243-4e2f-8103-7C616B022D6A"
CodeBesideClass="SPWFRilevaValore.Workflow1"
CodeBesideAssembly="SPWFRilevaValore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=dec95f95a7b44c08"
InstantiationUrl="_layouts/PaginaValore.aspx">
<Categories/>
<!-- Tags to specify InfoPath forms for the workflow; delete tags for forms that you do not have -->
<MetaData>
<AssociateOnActivation>false</AssociateOnActivation>
</MetaData>
</Workflow>
</Elements>
Creazione della pagina Asp.Net
La creazione del nostro progetto sta giungendo alla fine, ora rimane sola la parte web, in particolare la creazione di una pagina Asp.Net, la quale conterrà una casella di testo, ed un pulsante, quest’ultimo avrà il compito di avviare il workflow.
Aggiungiamo nella soluzione, un nuovo progetto di tipo applicazione Web Asp.net.
A differenza della maggior parte dei progetti, in questo progetto web, la pagina web, non sarà gestita con il code behind, ossia di avere due file, un file con il codice ed un altro con la parte html della pagina, ma sarà tutto incluso in una pagina aspx.
La pagina web, farà parte di una masterpage (application.master) ed eredita dalla pagina Microsoft.SharePoint.WebControls.LayoutsPageBase , da cui derivano tutte le pagine per sharepoint 2007.
Utilizzeremo i namespace di sharepoint ossia Microsoft.SharePoint, Microsoft.SharePoint.Workflow, Microsoft.SharePoint.Utilities, Microsoft.SharePoint.WebControls
La pagina, avrà una tabella contenente un controllo di tipo casella di testo, un controllo pulsante ed controllo label.
Di seguito si riporta la pagina Aspx, con il relativo codice e script html
VB.Net
<%@ Assembly Name="Microsoft.SharePoint.ApplicationPages, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%@ Page Language="VB"Inherits="Microsoft.SharePoint.WebControls.LayoutsPageBase" MasterPageFile="~/_layouts/application.master" EnableViewState="false" EnableViewStateMac="false" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="Microsoft.SharePoint.Workflow"%>
<%@ Import Namespace="Microsoft.SharePoint.Utilities"%>
<%@ Import Namespace="Microsoft.SharePoint.WebControls"%>
<script runat="server">
'dichiarazioni campi
'oggetto per la gestione del sito
Protected List As SPList
'oggetto elemento o riga di una lista
Protected ListItem As SPListItem
'classe che rappresenta l'assocazione di un workflow
Protected WorkflowAssociation As SPWorkflowAssociation
'oggetto che rappresenta un sito o un tipo di contenuto lista
Protected CCType As SPContentType
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim paramList As String = Request.Params("List")
Dim paramID As String = Request.Params("ID")
List = Web.Lists(New Guid(paramList))
ListItem = List.GetItemById(Convert.ToInt32(paramID))
Dim WorkflowAssociationID As Guid = New Guid(Request.Params("TemplateID"))
WorkflowAssociation = List.WorkflowAssociations(WorkflowAssociationID)
'verifico che non sia nulla, altrimenti ritento un associazione
If (WorkflowAssociation Is Nothing) Then
'ottengo il riferimento al workflow
Dim CTypeID As SPContentTypeId = CType(ListItem("ContentTypeId"), SPContentTypeId)
CCType = List.ContentTypes(CTypeID)
WorkflowAssociation = CCType.WorkflowAssociations(WorkflowAssociationID)
End If
If (WorkflowAssociation Is Nothing) Then Throw New SPException("Nessun Workflow trovato")
End Sub
Protected Sub BtnOk_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Try
Dim valore As String = txtNome.Text
Web.Site.WorkflowManager.StartWorkflow(ListItem, WorkflowAssociation, valore)
Catch ex As Exception
'nel caso che è un eccezione vado alla pagina degli errori
SPUtility.Redirect("Error.aspx", _
SPRedirectFlags.RelativeToLayoutsPage, _
HttpContext.Current, _
"ErrorText=" + "Errore")
End Try
SPUtility.Redirect(List.DefaultViewUrl, _
SPRedirectFlags.Default, _
HttpContext.Current)
End Sub
</script>
<asp:Content ID="Main" ContentPlaceHolderId="PlaceHolderMain" runat="server">
<table cellspacing="0" cellpadding="0" border="0" >
<TR>
<td valign=top><asp:Label Text="Nome:" ID="LblNome" runat=server></asp:Label></td>
<td> <asp:TextBox ID="txtNome" runat="server"></asp:TextBox></td>
</tr>
<tr>
<td colspan="1">
<asp:Button ID="BtnOk" runat="server" Text="OK" OnClick="BtnOk_Click" /></td>
</tr>
</TABLE>
</asp:Content>
C#
<%@ Assembly Name="Microsoft.SharePoint.ApplicationPages, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%>
<%@ Page Language="C#" Inherits="Microsoft.SharePoint.WebControls.LayoutsPageBase" MasterPageFile="~/_layouts/application.master" EnableViewState="false" EnableViewStateMac="false" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="Microsoft.SharePoint.Workflow"%>
<%@ Import Namespace="Microsoft.SharePoint.Utilities"%>
<%@ Import Namespace="Microsoft.SharePoint.WebControls"%>
<%--Codice C#--%>
<script runat="server">
//dichiarazioni campi
//oggetto per la gestione del sito
protected SPList List;
//oggetto elemento o riga di una lista
protected SPListItem ListItem;
//classe che rappresenta l'assocazione di un workflow
protected SPWorkflowAssociation WorkflowAssociation;
//oggetto che rappresenta un sito o un tipo di contenuto lista
protected SPContentType CType;
protected void Page_Load(object sender, EventArgs e)
{
string paramList = Request.Params["List"];
string paramID = Request.Params["ID"];
List = Web.Lists[new Guid(paramList)];
ListItem = List.GetItemById(Convert.ToInt32(paramID));
Guid WorkflowAssociationID = new Guid(Request.Params["TemplateID"]);
WorkflowAssociation = List.WorkflowAssociations[WorkflowAssociationID];
//verifico che non sia nulla, altrimenti ritento un associazione
if (WorkflowAssociation == null)
{ // ottengo il riferimento al workflow
SPContentTypeId CTypeID = (SPContentTypeId)ListItem["ContentTypeId"];
CType = List.ContentTypes[CTypeID];
WorkflowAssociation = CType.WorkflowAssociations[WorkflowAssociationID];
}
if (WorkflowAssociation == null)
throw new SPException("Nessun Workflow trovato");
}
protected void BtnOk_Click(object sender, EventArgs e)
{
try
{
string valore = txtNome.Text;
Web.Site.WorkflowManager.StartWorkflow(ListItem,
WorkflowAssociation,
valore);
}
catch (Exception ex)
{
//nel caso che è un eccezione vado alla pagina degli errori
SPUtility.Redirect("Error.aspx",
SPRedirectFlags.RelativeToLayoutsPage,
HttpContext.Current,
"ErrorText=" + "Errore");
}
SPUtility.Redirect(List.DefaultViewUrl,
SPRedirectFlags.Default,
HttpContext.Current);
}
</script>
<asp:Content ID="Main" ContentPlaceHolderId="PlaceHolderMain" runat="server">
<table cellspacing="0" cellpadding="0" border="0" >
<TR>
<td valign=top><asp:Label Text="Nome:" ID="LblNome" runat=server></asp:Label></td>
<td> <asp:TextBox ID="txtNome" runat="server"></asp:TextBox></td>
</tr>
<tr>
<td colspan="1">
<asp:Button ID="BtnOk" runat="server" Text="OK" OnClick="BtnOk_Click" /></td>
</tr>
</TABLE>
</asp:Content>
Terminata la preparazione del workflow e della pagina web, non resta che copiare i file (dll, aspx, xml) nella macchina (nel nostro caso in una virtual machine) e testare il tutto.
Configurazione ed installazione
A questo punto non ci resta che installare e configurare il nostro progetto, copiando i file nel computer in questione (nel mio caso è una macchina virtuale virtual pc 2007), nella cartella FEATURES (C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\) create una cartella (per esempio SPWFRilevaValore) in essa copiate i file xml (feature.xml e workflow.xml).
Copiante nella cartella assebly (C:\WINDOWS\assembly) la dll, in questo modo viene registrata nella GAC.
Ora non resta che copiare la nostra pagina Aspx, nella cartella delle pagine di sharepoint, e precisamente nella cartella layouts (C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS ).
A questo punto occorre eseguire dal prompt dei comandi, l’installazione del file feature,xml.
La registrazione avviene tramite il file stsadm.exe di seguito si riporta il comando da eseguire
stsadm.exe -o installfeature -filename SPWFRilevaValore\feature.xml -force
Riavviamo il WebServer IIS, tramite il comando IISReset.
Attivazione del WorkFlow
Terminata la fase di registrazione del componente non ci resta che attivare il workflow, apriamo il portale di sharepoint, e selezioniamo la nostra applicazione web, dal menu azioni sito, selezionare la voce impostazioni sito, nella sezione Amministrazione raccolta siti, selezionare la voce “Caratterestiche raccolta siti”
Figura 2
Nella pagina che viene aperta, troviamo l’elenco dei vari Workflow disponibili, tramite il pulsante attiva, del nostro Workflow rendiamo attivo il Workflow, come mostrato in figura 2.
Ora che il workflow è attivo, dobbiamo aggiungerlo nella nostra raccolta ed elenchi sito, dalla pagina delle impostazioni sito, selezioniamo la voce “Raccolte ed elenchi del sito”, che si trova nella sezione “amministrazione sito”.
Selezioniamo il contenuto con la dicitura “Documenti” .
Nella pagina che viene aperta, selezioniamo la voce “Impostazioni flusso di lavoro” che si trova nella sezione “Autorizzazioni e gestione”, a questo punto aggiungiamo il nostro workflow, valorizzando i campi di tale pagina.
Esecuzione del Workflow.
Ora che nel nostro progetto è stato creato ed aggiunto il workflow, non ci resta che eseguirlo, nella cartella documenti, selezioniamo un documento e dal menu di scelta rapida, selezioniamo la voce “Flussi di lavoro”, nella pagina che viene aperta (figura 3) , facciamo click sul nostro workflow.
Figura 3
A questo punto verrà avviata la nostra pagina (figura 4), come illustrato precedentemente, il worfklow, avrà il compito di visualizzare il testo della casella di testo nella cronologia del flusso di lavoro (fate clic sulla voce completato). (figura 5)
Figura 4
Figura 5
Conclusioni:
In questo articolo è stato illustrata la tecnica di come eseguire un workflow da una pagina Asp.net, tramite la parola download è possibile scaricare il file di esempio.
Download