Associating a OOTB Approval WF to a Document Library using c#
A few weeks ago i have been struggling with programmaticly adding a standard approval workflow to a custom list.
Since this is an out of the box functionality I expected this to go pretty smoothly… NOT… ![]()
It seemed to be some xml manipulations which is pretty different from SharePoint 2007.
The basic steps for adding the standard approval WF to a library is pretty easy:
string workflowAssocName = "Your association name";
SPWorkflowTemplate workflowTemplate = oWeb.WorkflowTemplates.GetTemplateByName("Approval - SharePoint 2010", System.Globalization.CultureInfo.CurrentCulture);
SPList myList = oWeb.Lists["LibraryName"];
The workflowAssocName is nothing but the “display name” of the workflow association on the list. This can be anything.
// Try to get workflow history and task list historyList = TryGetList(oWeb, Constants.WORKFLOW_VERGADERWERKRUIMTE_DOCUMENTEN_LISTS_HISTORY, "", true, SPListTemplateType.WorkflowHistory); taskList = TryGetList(oWeb, Constants.WORKFLOW_VERGADERWERKRUIMTE_DOCUMENTEN_LISTS_TASKS, "", true, SPListTemplateType.Tasks);
TryGetList is a function which will get the list if it allready exists at the site. If not, the list will be created.
private SPList TryGetList(SPWeb oWeb, string listTitle, string listDescription, Boolean hidden, SPListTemplateType Type)
{
SPList oList;
try
{
oList = oWeb.Lists[listTitle];
return oList;
}
catch (ArgumentException exc)
{
// Create list
Guid listGuid = oWeb.Lists.Add(listTitle, listDescription, Type);
oList = oWeb.Lists[listGuid];
oList.Hidden = hidden;
oList.Update();
return oList;
}
}
To create the workflow association add this code.
// Create workflow association SPWorkflowAssociation workflowAssociation = SPWorkflowAssociation.CreateListAssociation( workflowTemplate, workflowAssocName, taskList, historyList); // Set workflow parameters workflowAssociation.AllowManual = false; workflowAssociation.AutoStartCreate = true; workflowAssociation.AutoStartChange = true; workflowAssociation.ContentTypePushDown = false; // The AssociationData property represents for the settings that user see in 2nd screen when creating workflow in SharePoint UI var associationDataXml = XElement.Parse(workflowAssociation.AssociationData); // Update modifed xml segment back to WorkflowAssociation object workflowAssociation.AssociationData = SetAssociationData(oWeb.ParentWeb, associationDataXml); // Add workflow association to my list myList.WorkflowAssociations.Add(workflowAssociation); // Enable workflow workflowAssociation.Enabled = true; myList.Update();
The tricky part comes in at this line
workflowAssociation.AssociationData = SetAssociationData(oWeb.ParentWeb, associationDataXml);
AssociationData is an xml format of the data which you normally enter in the association form. (When adding a standard approval workflow using the UI).
private String SetAssociationData(SPWeb oWeb, XElement associationDataXml)
{
String sDate = String.Empty;
XNamespace dNamespace = @"http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields";
XNamespace pcNamespace = @"http://schemas.microsoft.com/office/infopath/2007/PartnerControls";
XNamespace dfsNamespace = @"http://schemas.microsoft.com/office/infopath/2003/dataFormSolution";
XNamespace MyNamespace = @"http://schemas.microsoft.com/office/infopath/2003/myXSD";
XNamespace XsiNamespace = @"http://www.w3.org/2001/XMLSchema-instance";
XElement propertiesWrapper = associationDataXml.Element(dfsNamespace + "dataFields").Element(dNamespace + "SharePointListItem_RW");
propertiesWrapper.SetElementValue(dNamespace + Constants.WORKFLOW_SETTINGS_CANCELONREJECTION, true);
propertiesWrapper.SetElementValue(dNamespace + Constants.WORKFLOW_SETTINGS_CANCELONCHANGE, true);
propertiesWrapper.SetElementValue(dNamespace + Constants.WORKFLOW_SETTINGS_APPROVEWHENCOMPLETE, true);
propertiesWrapper.SetElementValue(dNamespace + Constants.WORKFLOW_SETTINGS_ENABLECONTENTAPPROVAL, true);
propertiesWrapper.SetElementValue(dNamespace + Constants.WORKFLOW_SETTINGS_EXPANDGROUPS, false);
// Reviewers is Approvers in UI
XElement xAssignement = associationDataXml.Element(dfsNamespace + "dataFields").Element(dNamespace + "SharePointListItem_RW").Element(dNamespace + "Approvers").Element(dNamespace + "Assignment");
string ApprovalGroup = "Approver Group Name";
xAssignement.Element(dNamespace + "Assignee").Add(
new XElement(pcNamespace + "Person",
new XElement(pcNamespace + "DisplayName", ApprovalGroup),
new XElement(pcNamespace + "AccountId", ApprovalGroup),
new XElement(pcNamespace + "AccountType", "SharePointGroup")
)
);
return associationDataXml.ToString();
}
Tip: Before doing this, check the associationdata property of a workflow association added through the UI. (You can open this property using SharePoint Manager 2010).
At first i define some namespaces since they are used in this xml, this means i can not access nodes without including the namespace.
The next step is changing the necessary properties. (Like cancel on reject etc) I have changed 5 values, tho you can change all of them. For a list of available properties check the xml file as explained in the tip.
The last step is to make sure the correct SharePoint User or Group is set as approver for this WorkFlow. It took me a while to get this.
But it seems that there is an empty Assignee tag which is the container for our approvers.
This tag expects a Person child node which also expects 3 child nodes: DisplayName, AccountId and AccountType.
When running this code on an existing SharePoint document library, it should successfully attach a workflow and create a task when a new item is added.
-
Tom
-
http://blog.voltje.be Frederik Prijck
-
Vandeput
-
http://blog.voltje.be Frederik Prijck
-
Christophe
-
http://blog.voltje.be Frederik Prijck
Categories
- .NET Development (10)
- News (1)
- No programming (2)
- PowerShell (2)
- Sharepoint 2010 (25)
- Silverlight 3 (4)
- Silverlight 4 (2)
- UX (1)
- Windows Phone 7 (1)
Tags
approval ASP ASPMVC association BCS bug c# CBA Claims Client Object Model COM Deployment Design pattern Entity Framework eventreceiver Field Fields generics Google calendar Interaction javascript listadded Managed Metadata MethodNotImplemented MMS Model Binding Mvvm Office office 2003 PowerShell properties reflection runtime save conflict Sharepoint Silverlight Site column Site Url synchronous Unit Testing Windows Phone 7 WorkFlow WP7 Xaml xmlRecent Comments
- need support/materials for developing external lists with visual studio 2010 | Question and Answer on Deploying an External List using Visual Studio 2010
- Marc Blakely on Deploying an External List using Visual Studio 2010
- frederikprijck on Mocking Entity Framework using ObjectContext and database first
- Ben Anderson on Mocking Entity Framework using ObjectContext and database first
- frederikprijck on Mocking Entity Framework using ObjectContext and database first





