Sharepoint 2010 – programmatically set workflow initiation parameters
If you trigger workflows from the code behind of a custom webpart you might want to set some of the workflow initiation parameters to runtime values. I’ve seen some pretty ugly attempts to do this by alternating the SPWorkflowAssociation.AssociationData object using string.Replace for instance.. To save others the time and effort figuring out this I thought I’d share a method I wrote where this is done in a more proper and reliable way.
For simplicity the namespace is hardcoded, but you should be able to figure that part out for yourself. This is the default namespace, and will work unless you’ve tampered with it.
It pretty much just accepts the original association data (XML based) and the name of the initiation parameter plus the new value (this is only for string based variables, but you could easily add support for other types as well).
private static string AddVariableToWorkflowAssociationData(string originalAssociationData, string variableName, string variableValue) { XNamespace dfs = "http://schemas.microsoft.com/office/infopath/2003/dataFormSolution"; XNamespace d = "http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields"; var associationDataXml = XElement.Parse(originalAssociationData); if (associationDataXml == null || associationDataXml.Element(dfs + "dataFields") == null || associationDataXml.Element(dfs + "dataFields").Element(d + "SharePointListItem_RW") == null || associationDataXml.Element(dfs + "dataFields").Element(d + "SharePointListItem_RW").Element(d + variableName) == null) { _log.Warn("AddVariableToWorkflowAssociationData() unable to find node '" + variableName + "' in association data"); return originalAssociationData; } _log.Info("Setting workflow parameter '" + variableName + "' to '" + variableValue + "'"); var nodeToChange = associationDataXml.Element(dfs + "dataFields").Element(d + "SharePointListItem_RW").Element(d + variableName); nodeToChange.SetValue(variableValue); return associationDataXml.ToString(); }
Invoke this method by getting a reference to the workflow you want to trigger (SPWorkflowAssociation), call my method with the original association data, and use the return value when starting the workflow:
string enhancedAssociationData = AddVariableToWorkflowAssociationData(wrkFl.AssociationData, "MyVeryOwnAssociationParameter", "SomeCrazyValue!!"); enhancedAssociationData = AddVariableToWorkflowAssociationData(enhancedAssociationData, "AnotherAssociationParameter", "AndYetAnotherCrazyValue"); siteColl.WorkflowManager.StartWorkflow(record, wrkFl, enhancedAssociationData, true);
Some of this code was altered on the fly for this blog post so compilation is not guaranteed. However, if you’re this deep into it to start with you should be capable of resolving that anyway!
