Udostępnij za pośrednictwem


Workflow sui sondaggi? Unsupported!

Ebbene si, è inutile che proviate a configurare il vostro bel workflow sulla lista di un sondaggio perché non potrà mai funzionare. Ho infatti trovato questa KB che lo sancisce:

The status of a workflow appears as "Failed to Start" when you try to start a workflow from a survey response in Windows SharePoint Services 3.0

Prima che trovassi la KB mi sono messo a cercare di capire come mai il mio semplice workflow non partiva dopo aver sottomesso la risposta ad un sondaggio. O meglio, cercava di partire e si arenava miseramente segnalando "Failed to Start".

Nei log ho trovato il seguente errore:

RunWorkflow: System.ArgumentException: Invalid field name. {ae069f25-3ac2-4256-b9c3-15dbc15da0e0} at Microsoft.SharePoint.SPFieldCollection.GetFieldById(Guid fieldId, Boolean bThrowException) at Microsoft.SharePoint.SPFieldCollection.get_Item(Guid id) at Microsoft.SharePoint.SPListItem.get_Item(Guid fieldId) at Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties..ctor(SPWorkflow workflow, Int32 runAsUserId, String associationData, String initiationData) at Microsoft.SharePoint.Workflow.SPWinOEWSSService.MakeActivation(SPWorkflow workflow, SPWorkflowEvent e) at Microsoft.SharePoint.Workflow.SPWinOeEngine.RunWorkflow(Guid trackingId, SPWorkflowHostService host, SPWorkflow workflow, Collection`1 events, TimeSpan timeOut) at Microsoft.SharePoint.Workflow.SP..

Giocando con il Reflector ho capito che il problema è dovuto al fatto che, durante l'attivazione del workflow, Sharepoint tenta di accedere al campo GUID (FieldID=ae069f25-3ac2-4256-b9c3-15dbc15da0e0) dell'item a cui è associata l'istanza del workflow ma a quanto pare gli item della lista di tipo sondaggio non hanno tale attributo! Ecco quindi perché non potrà mai funzionare e quindi perché viene dichiarato come Unsupported.

Ecco qualche dettaglio del codice disassemblato:

Il metodo MakeActivation dell'oggetto SPWinOEWSSService è:

 internal static void MakeActivation(SPWorkflow workflow, SPWorkflowEvent e)
{
    e.IsActivation = true;
    e.EventType = typeof(ISharePointService).GUID;
    e.EventName = "OnWorkflowActivated";
    string associationData = workflow.ParentAssociation.AssociationData;
    string initiationData = null;
    if ((e.EventData != null) && (e.EventData.Length > 0))
    {
        initiationData = e.EventData[0] as string;
    }
    if (e.IsAutostart && (initiationData == null))
    {
        initiationData = associationData;
    }
    e.EventData = new object[] { workflow.InstanceId, 
                                 new SPWorkflowActivationProperties(workflow, <br>                                               e.RunAsUserId, <br>                                               associationData, <br>                                               initiationData)  };
}
 Il costruttore di SPWorkflowActivationProperties è:

 internal SPWorkflowActivationProperties(SPWorkflow workflow, 
                                        int runAsUserId, 
                                        string associationData, 
                                        string initiationData)
{
    this.m_itemId = -1;
    this.m_workflow = workflow;
    if (!this.SuperUserWorkflow)
    {
        throw new ArgumentException();
    }
    this.m_associationData = associationData;
    this.m_initiationData = initiationData;
    this.m_workflowId = this.Workflow.InstanceId;
    this.m_itemId = this.Item.ID;
    this.m_listId = this.List.ID;
    this.m_taskListId = this.Workflow.TaskListId;
    this.m_histListId = this.Workflow.HistoryListId;
    this.m_templateName = this.Workflow.ParentAssociation.Name;
    this.m_itemGuid = new Guid((string) this.Item[SPBuiltInFieldId.GUID]); 
    this.m_webId = this.Web.ID;
    this.m_siteId = this.Site.ID;
    if (runAsUserId != this.OriginatorUser.ID)
    {
        throw new ArgumentException();
    }
    this.m_originator = this.OriginatorUser.LoginName;
    this.m_originatorEmail = this.OriginatorUser.Email;
    this.m_siteUrl = this.Site.Url;
    this.m_webUrl = this.Web.Url;
    this.m_itemUrl = this.Item.Url;
    this.m_listUrl = this.List.RootFolderUrl;
    this.m_histListUrl = this.HistoryList.RootFolderUrl;
    this.m_taskListUrl = this.TaskList.RootFolderUrl;
}

Da cui si evince il tentativo di accesso al field indicato da SPBuiltInFieldId.GUID che infatti è quello indicato nei log:

 static SPBuiltInFieldId()
{
    [...]
    GUID = new Guid("{ae069f25-3ac2-4256-b9c3-15dbc15da0e0}"); 
    [...] 
}

HTH