When you are adding Workflow Initiation Form to your Visual Studio project, then Visual Studio generating aspx page with buttons and code behind with some lines of code.
SharePoint workflow can be associated with list, site or content type. This generated code works fine with workflows associated with List, but if your workflow is associated with list content type, then when you will click Start button – you will get exception.
This error is in method StartListWorkflow() at following line of code:
SPWorkflowAssociation association =
this.workflowList.WorkflowAssociations[new Guid(this.associationGuid)];
Exception will be thrown on next line, because association will null, if workflow was associated with content type.
To solve this problem you can replace this line of code with following code:
SPWorkflowAssociation association =
this.workflowList.WorkflowAssociations[new Guid(this.associationGuid)];
if (association == null)
{
association = workflowListItem.ContentType.WorkflowAssociations[new Guid(associationGuid)];
}
Now entire method should look like following:
private void StartListWorkflow()
{
SPWorkflowAssociation association =
this.workflowList.WorkflowAssociations[new Guid(this.associationGuid)];
if (association == null)
{ association = workflowListItem.ContentType.WorkflowAssociations[new Guid(associationGuid)];
}
this.Web.Site.WorkflowManager.StartWorkflow(workflowListItem, association, GetInitiationData());
SPUtility.Redirect(this.workflowList.DefaultViewUrl, SPRedirectFlags.UseSource,
HttpContext.Current);
}
When it is needed to add Workflow Association programmatically, then it requires instance of Workflow History List. There is 2 possibilities: list already exists or you should create it.
private static SPList GetHistoryList(SPWeb web)
{
string historyListName = SPResource.GetString(
"DefaultWorkflowHistoryListName",
new object[0]);
SPList historyList = web.GetListByName(historyListName);
if (historyList != null)
{
return historyList;
}
// create list if there is no such list yet
Guid listGuid = web.Lists.Add(
historyListName,
string.Empty,
SPListTemplateType.WorkflowHistory);
historyList = web.Lists.GetList(listGuid, false);
historyList.Hidden = true;
historyList.Update();
return historyList;
}
Here is in use extension method for SPWeb which returns null if list not found (default methods throwing Exception in this case). Here is the code of this extension method:
public static SPList GetListByName(this SPWeb web, string listName)
{
try
{
return SPUtility.GetSPListFromName(web, Guid.Empty, null, null,
listName);
}
catch
{
return null;
}
}