Tuesday, 1 May 2012

SharePoint 2010: Workflow Association element


In MOSS 2007, WSS 3.0, associating workflow with list / content type is done programmatically usually in feature receiver code. This still holds true in SharePoint 2010 as well. I am not going into details about it but you can explore SPWorkflowAssociation API if you are interested. Instead, I am going to talk about new WorkflowAssociation element added in SharePoint 2010 which also can be used to associate the workflows to the list/ list content types or site in declarative (xml, no code) manner.

To start, I googled WorkflowAssociation element and to my surprise I have not found any documentation anywhere neither at MSDN not at any blogs. So I thought to figure it out myself. I manually associated Disposition Approval workflow to one my custom list through browser. Then I saved the site as site template, downloaded the site template wsp into my physical local drive, created new Visual Studio project using Import SharePoint Solution Package project template and selected the saved site template wsp. Bingo! One of the imported items shown by Visual Studio project wizard was the workflow association element created by me.

Figure 1 : Select Workflow Association item to Import


I selected it and clicked Finish button for import. Here is the generated workflow Association element manifest xml.


<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<WorkflowAssociation Name="Disposition Approval Workflow" 
                     Description="Manages document expiration and retention by allowing participants to decide whether to retain or delete expired documents." 
                     Id="{6947caf3-7463-4065-b79c-e5e3555f2629}" 
                     BaseTemplateId="{dd19a800-37c1-43c0-816d-f8eb5f4a4145}" 
                     ParentContentType="List" 
                     ParentList="Lists/Demo List" 
                     ParentWeb="TRUE" 
                     TaskList="Lists/Tasks" 
                     TaskListTitle="Tasks" 
                     HistoryList="Lists/Workflow History" 
                     HistoryListTitle="Workflow History" 
                     StatusColumnShown="FALSE" 
                     InternalNameStatusField="Disposit" 
                     RequireManagePermission="ViewListItems, EditListItems, ManageLists" 
                     Configuration="69659" 
                     AssociationData="" 
                     ContentTypeName="" 
                     ContentTypeId="0x" 
                     xmlns="http://schemas.microsoft.com/sharepoint/" />
</Elements>



Well, almost all attributes of the WorkflowAssociation tag are self-explanatory but still listing the purposes of them below. For some, even I have doubts. Leave the comment to either clarify those or in case of any discrepancy in my findings.

  • Name
    This is the name of the workflow association.
  • Description
    This is the description of the workflow association.
  • ID
    New GUID of the workflow association.
  • BaseTemplateId
    GUID of the workflow template which needs to be associated.
  • ParentContentType
    This determines whether workflow is associated to list, list content type or site.

    Possible Values
    When
    ContentType
    workflow is supposed to be associated with list content type.
    Web
    workflow is supposed to be associated with site
    List
    workflow is supposed to be associated with list

  • ParentList
    Name of the list to which workflow needs to be associated. In case of site workflow, leave the value as empty.
  • ParentWeb
    Not clear. I noticed that the value is always set to “TRUE” for both Site workflow and list workflows.
  • TaskList
    This is the Workflow Task list url to be used in workflow.
  • TaskListTitle
    This is the Workflow Task list name to be used in workflow.
  • HistoryList
  • This is the Workflow History list url to be used in workflow.
  • HistoryListTitle
    This is the Workflow History list name to be used in workflow.
  • StatusColumnShown
    TRUE/FALSE
  • InternalNameStatusField
    This should contain the internal name of the workflow status column.
  • RequireManagePermission
    Permissions to control who can execute the workflow.

    Possible permission Values
    When
    ViewListItems, EditListItems

    This is the default value.
    ViewListItems, EditListItems
    ManageLists
    When only users having ManageLists permission can execute the workflow

  • Configuration
    This is an integer number which controls when workflow is to be triggered. I have elaborated my findings about it separately in this blog below.
  • AssociationData
    This is workflow association data in xml format.
  • ContentTypeName
    Name of the list content type to which workflow needs to be associated. Leave it empty for list/ site workflows
  • ContentTypeId
    GUID of the list content type to which workflow needs to be associated. Remove this attribute as mentioning ContentType name attribute is enough.
  • CategoryName
    Not clear
  • RootWebOnly
    TRUE/ FALSE
Initially, I got confused with the different values of Configuration attribute generated by importing the Site Template wsp. Hence I tried digging into SharePoint assemblies for SPWorkflowAssociation API using disassembler tool Telerik JustDecompile to see what role does this attribute play and what are its possible values. I found it as a flagged Enum.

Figure 2 : Configuration Enum


Hence I quickly wrote a code which can be used to determine the configuration attribute value…


using System;
using System.Diagnostics;
using System.IO;
using System.Net;
namespace SPConsoleProject
{
    class Program
    {
        [Flags]
        public enum Configuration
        {
            None = 0,
            AutoStartAdd = 1,
            AutoStartChange = 2,
            AutoStartColumnChange = 4,
            AllowManualStart = 8,
            HasStatusColumn = 16,
            LockItem = 32,
            Declarative = 64,
            NoNewWorkflows = 128,
            MarkedForDelete = 512,
            GloballyDisabled = 1024,
            CompressInstanceData = 4096,
            SiteOverQuota = 8192,
            SiteWriteLocked = 16384,
            AllowAsyncManualStart = 32768,
            SkipContentTypePushDown = 65536
        }

        static void Main(string[] args)
        {
            Configuration a =   Configuration.SkipContentTypePushDown | 
                                Configuration.CompressInstanceData |
                                Configuration.AutoStartAdd |
                                Configuration.AllowManualStart | 
                                Configuration.AutoStartChange |
                                Configuration.HasStatusColumn;
            Console.WriteLine((int)a);
            Console.ReadLine();
        }
        
    }
}


Here are some examples of Configuration values with their corresponding enum values for Disposition Approval workflow.

Behavior
Value
Configuration Enum value
AllowManuallyAndOnCreated
69657
Configuration.SkipContentTypePushDown | 
Configuration.CompressInstanceData |
Configuration.AutoStartAdd |
Configuration.AllowManualStart | 
Configuration.HasStatusColumn

AllowManuallyAndOnCreatedAndOnEdited
69659
Configuration.SkipContentTypePushDown | 
Configuration.CompressInstanceData |
Configuration.AutoStartAdd |
Configuration.AllowManualStart | 
Configuration.AutoStartChange |
Configuration.HasStatusColumn

AllowManuallyAndOnEdited
69658
Configuration.SkipContentTypePushDown | 
Configuration.CompressInstanceData |
Configuration.AllowManualStart | 
Configuration.AutoStartChange |
Configuration.HasStatusColumn

For Site Workflow
4184
Configuration.CompressInstanceData |
Configuration.AllowManualStart |
Configuration.Declarative |
Configuration.HasStatusColumn


Well, I have mentioned all these details about Configuration value just to have some insights on how it is calculated. In real world, I don’t think you will need to bother about it as you can always generate your WorkflowAssociation element manifest file using method described at the start of this post.

Few other important findings/ suggestions:
  1. Ensure that the workflow status field mentioned InternalNameStatusField attribute is present in the list/ content type to which you want to associate the workflow. Otherwise, you will get some correlation errors for which you will need to dig the ULS logs.
  2. Do not mention the content type ID in case workflow is associated with the site or list content type. Content type name is sufficient.
  3. I was not able to create site content type workflow association. It was not captured when I saved the site as site template. Looks like a bug in Save as site template feature of SharePoint. Hope someone from Microsoft is reading.
  4. Ensure History or Tasks list to be used in workflow association is already present. Otherwise the feature activation will give file not found error.
  5. I am yet to determine the workflow association configuration when it should run on publication of major version of the document. I will give a try in free time. In case you figure it out before me, please leave a comment.

Thinking to create a Visual Studio Item Template for Workflow Association for my MP.SPDevExt project. Not decided though.

3 comments:

  1. Hi Parwej,

    Thanks for sharing, that was helpfull for me.

    ReplyDelete
  2. The best explanation about workflow.

    Very Very Good.

    ReplyDelete
  3. CategoryName - Not clear

    I guess is the one used by SPWorkflowManager.GetWorkflowTemplatesByCategory method

    http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.workflow.spworkflowmanager.getworkflowtemplatesbycategory.aspx

    ReplyDelete