Programmatically assigning a workflow to a Sitecore item

Recently I wanted to use the Sitecore API to programmatically create a new version of an item and then also set a workflow on that new version. I didn’t expect this to be a difficult task but I ran into an issue that needed some debugging.

My first attempt at assigning a workflow to an item involved directly setting the values of the “__Workflow” (Sitecore.FieldIDs.Workflow) field and the “__Workflow state” (Sitecore.FieldIDs.WorkflowState) field as seen below.

var db = Sitecore.Context.Database;
Item workflowItem = db.GetItem("{DF7F337F-13F6-412C-A333-8273C2082E56}");
Item workflowState = db.GetItem("{E7BA2D86-1232-43E7-A78B-FB394D75ECE1}");
if (workflowItem == null || workflowState == null) return;
Item newVersion = item.Versions.AddVersion();

newVersion.Editing.BeginEdit();
try
{
    newVersion.Fields[Sitecore.FieldIDs.Workflow].Value = workflow.ID.ToString();
    newVersion.Fields[Sitecore.FieldIDs.WorkflowState].Value = workflowState.ID.ToString();
}
finally
{
    //Close the editing state
    newVersion.Editing.EndEdit();
}

This approach seemed natural to me since I’m so used to assigning field values in this way. While this seemed to work at first glance, there was a significant problem that forced me to find a new solution. When I navigated to the Workbox I was able to see the new version of the item like I expected but I was not able to find it in the RSS feed for that workbox. Believe it or not, setting a workflow using the above method meant that the new version did not appear in the RSS feed for that workbox even though it did appear in the workbox listing. This signaled to me that I was probably doing something wrong.

So instead, here was my second attempt at assigning a workflow to an item.

var db = Sitecore.Context.Database;
Item workflowItem = db.GetItem("{DF7F337F-13F6-412C-A333-8273C2082E56}");
if (workflowItem == null) return;
Item newVersion = item.Versions.AddVersion();

Sitecore.Workflows.IWorkflow workflow = db.WorkflowProvider.GetWorkflow(workflowItem);
workflow.Start(newVersion);

I expected the code above to work straight away but instead I found myself with a NullReferenceException thrown. What the…?

What was the problem? It turns out that even though the documentation for the “GetWorkflow” method says it accepts both an Item and a string GUID of an item, passing an item does not seem to work. So after some quick debugging I called the “GetWorkflow” using a string parameter and everything was good to go.

var db = Sitecore.Context.Database;
Item workflowItem = db.GetItem("{DF7F337F-13F6-412C-A333-8273C2082E56}");
if (workflowItem == null) return;
Item newVersion = item.Versions.AddVersion();

Sitecore.Workflows.IWorkflow workflow = db.WorkflowProvider.GetWorkflow(workflowItem.ID.ToString());
workflow.Start(newVersion);

Perfect. I finally was able to set a workflow for my newly created item version AND it appeared in the RSS feed for my workbox!

Note: I had no need to programmatically move the new item version forward to a different workflow state, but if necessary you should use something similar to the following snippet. This ensures that workflow actions are executed when moving to a new state.

workflow.Execute(workflowCommandId, newVersion , "Example comment", false);
Advertisements
Posted in Sitecore, Sitecore Bug

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s