Microsoft MVP Logo

In the last post I showed you how to create a simple task using the out-of-the-box (OOTB) task content type that ships with SharePoint 2013: Workflow Task (SharePoint 2013). Then we build off this and creating a custom task that had a new form field. In this post I want to show you how we can use this approach to create custom outcomes buttons in our task forms. Unfortunately in this process you'll see a bug in the SharePoint/Workflow engine for our custom outcomes… but no worries. I'll show you how to get around that.

The way you create custom buttons at the bottom of your task form is by creating custom outcome columns. The process is quite simple:

  • Create a new site column that is based on the field type OutcomeChoice and add your choices
  • Add this column to your custom task content type
  • Use it!

In the same project that I finished the last blog post with I'll add a new site column:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">  
  <Field
       ID="{2e30db97-45c9-4c50-8cc4-06ba62dc7f73}"
       Name="CustomOutcome"
       DisplayName="Custom Outcome"
       Type="OutcomeChoice"
       Required="FALSE"
       Group="AC">
    <CHOICES>
      <CHOICE>Red Pill</CHOICE>
      <CHOICE>Blue Pill</CHOICE>
    </CHOICES>
  </Field>
</Elements>

Now I'll add it to my content type:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <!-- Parent ContentType: Workflow Task (SharePoint 2013) (0x0108003365C4474CAE8C42BCE396314E88E51F) -->
  <ContentType ID="0x010800003365C4474CAE8C42BCE396314E88E51F404DE3BCDECF4310BEBC2593136E13F4" 
            Name="Custom Task" 
            Group="AC" 
            Inherits="TRUE" 
            Version="0">
    <FieldRefs>
      <FieldRef ID="{baeea9f4-3589-420c-80ee-27e58c4286c2}" Name="MonthsColumn" />
      <FieldRef ID="{2e30db97-45c9-4c50-8cc4-06ba62dc7f73}" Name="CustomOutcome" />
    </FieldRefs>
  </ContentType>
</Elements>

Now go back into the task edit dialog within the Visual Studio designer and update the task to use your new column. But wait… look at what you get in the edit mode of the task that gets created:


That's not what we want! I want to only show my items.

The Custom Outcome Column Bug

What you are seeing is a little bug in the SharePoint/Workflow engine where it keeps rendering the default outcome column. You may be thinking this shouldn't be hard to address, but let me save you the time:

  • Can't I just make sure I remove the default column that is in the Workflow Task (SharePoint 2013) content type I'm inheriting from?Unfortunately not, the defaults still get rendered
  • Can't I just set my custom content type to not inherit all the fields from the Workflow Task (SharePoint 2013) content type using the <RemoveFieldRef> node? Nope, the defaults still get rendered.
  • What if I create my own custom content type that doesn't inherit from the Workflow Task (SharePoint 2013) content type? The problem with this is you can't select your custom content type in the workflow task designer as an option because it filters out all content types that don't inherit from the Workflow Task (SharePoint 2013) content type.
This bug exists today, as of writing, that is based on the following. At some point in the future it will likely get addressed:
  • Service Bus 1.0 + February 2013 Cumulative Update
  • Workflow Bus 1.0 + February 2013 Cumulative Update
  • SharePoint 2013 RTM + March 2013 Public Update
For details on getting your envionrment updated to this level, refer this post: Updates for SharePoint 2013 Workflow.

My Custom Outcome Column Workaround

I've figured out a way around this. It works great for me, but I have to admit I'm not sure if any issues creep up anywhere else. I don't think so because my tweak is isolated to just the task list and so far in my testing it looks fine. However you know how big this product is… one day I might have my second mea culpa post… so consider disclaimer issued!

What I've found is that if you create a new content type that inherits from the base Task content type, add your custom outcome column and then add the other special site column called the WorkflowInstanceId. This works, but the problem is that Visual Studio 2012's workflow designer doesn’t respect your decision because it won't show any content types that don't derive from Workflow Task (SharePoint 2013). However there's a way around this. So here are the steps I do, in this order, to make it work. It will work other ways, but this is what works best form me.

Step 1: Setup the Custom Task Content Type with a Custom Outcome

This step is easy… do the exact same thing you did above where you had two sets of outcome column choices on the screen when you were in the edit mode for a task. Stop debugging and move onto the real workaround.

Step 2: Update the Custom Task Content Type Inheritance

What you are going to do is break the inheritance of your custom task content type and inherit from the base Task content type. This way you'll break off the default outcome column from being rendered. To do this, go into the element manifest for your content type and remove the part of the content type ID that inherits from the Workflow Task (SharePoint 2013) content type; specifically you want to remove this string: 003365C4474CAE8C42BCE396314E88E51F

Next you want to add the WorkflowInstanceId column to your content type. You can find this in the content type definition of the Workflow Task (SharePoint 2013) so your content type should now look like this:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <ContentType ID="0x010800404DE3BCDECF4310BEBC2593136E13F4" 
            Name="Custom Task" 
            Group="AC" 
            Inherits="TRUE" 
            Version="0">
    <FieldRefs>
      <FieldRef ID="{baeea9f4-3589-420c-80ee-27e58c4286c2}" Name="MonthsColumn" />
      <FieldRef ID="{2e30db97-45c9-4c50-8cc4-06ba62dc7f73}" Name="CustomOutcome" />
      <FieldRef ID="{1F30D200-0D4E-4C8A-A7EB-2E49815BF2BE}" Name="WorkflowInstanceId" />
    </FieldRefs>
  </ContentType>
</Elements>

The next thing you need to do is update the places you've referenced the content type. Go into the <ContentTypeBindings> element manifest you created and modify the content type ID. Next up is the workflow's SingleTask activity. The challenge here is that the designer won't allow you to fix it. So what you need to do is update the raw XAML. To do this, right click the workflow.xaml file and select Open With and then select XML (Text) Editor.

Find the <SingleTask> element and look for the attribute ContentTypeId. You want to make this one be the same as your custom task content type ID.

Save your changes and hit F5 to see everything work!

Want the code for this sample? Come and get it: SP2013Wf-CustomTaskOutcome.zip

Disclaimer

Like I said above, I'm pretty sure this is going to work just fine until we get a fix. However, keep in mind that once this bug is fixed you have to decide if you want to leave this workflow as is, or if you want to change it to inherit from the correct task. The other angle is that there may be something in SharePoint, or some other product an ISV has build, that is expecting tasks to be based on the Workflow Task (SharePoint 2013) content type… and if so, I just showed you how to break it.

For me, I think this work around is sufficient. I think the disclaimer I pitch above is a bit dramatic and over cautious, but I wanted to be as transparent about this as possible.

Comments powered by Disqus