Getting and Setting Managed Metadata Fields in SharePoint 2013 Workflows

In many workflow scenarios, you'll want to get a field value from a list item in one list and apply that value to a list item on another list. With most field types, you can do this easily using workflow variables and built-in list actions in SharePoint Designer 2013. However, it's widely acknowledged that working with managed metadata fields in SharePoint workflows is a bit of a nightmare. To get around the problem, I built some custom workflow activities to get and set managed metadata fields in SharePoint Designer workflows.

This is the first of a three-part series on working with managed metadata fields in workflows:


Problem overview


Managed metadata fields are similar in structure to lookup fields, with complex values of type TaxonomyFieldValue. If you use the REST API to get or set the value of a managed metadata field named Customer, the JSON payload looks something like this:

{"Customer":{
   "__metadata":{"type":"SP.Taxonomy.TaxonomyFieldValue"},
   "Label":"n",
   "TermGuid":"nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn",
   "WssId":n }}

You can see that the managed metadata field consists of three property values, where TermGuid uniquely identifies the term, Label represents the display name for the term, and WssId is the ID of the list item that stores the term locally in the TaxonomyHiddenList list.
Unfortunately, the built-in list actions in SharePoint Designer 2013 (Create List Item, Update List Item, Set Field in Current Item) will only allow you to set a managed metadata field to a string value. When you try to update a managed metadata field value, SharePoint is expecting a complex type in the format you can see above. However, any value you supply through a built-in list action in SharePoint Designer gets wrapped in quote marks and is treated as a string literal. Behind the scenes, SharePoint throws an InvalidClientQuery exception when it receives the request from your workflow, with the following message:

An unexpected 'PrimitiveValue' node was found when reading from the JSON reader. A 'StartObject' node was expected.


Distractions


You may have read that you can specify string values for managed metadata fields using the format <WssId>;#<Label>|<TermGuid>. That may have worked in SharePoint 2010 workflows, but it doesn't work in SharePoint Designer 2013 where workflow activities are built on the client web services. The error is clear - SharePoint is expecting a complex object, and it complains when the workflow manager sends it a string. It's also worth noting that the built-in list actions in SharePoint Designer don't expose hidden taxonomy fields.

Solution overview


To update the value of a managed metadata field, your workflow needs to send a request that looks something like this:

POST http://team.jason.net/_api/web/lists/getbyid(guid'fe31bb2a-8737-4085-be2e-70368115c688')/Items(29) HTTP/1.1
If-Match: *
X-HTTP-Method: MERGE
Accept: application/json; odata=verbose
Content-Type: application/json; odata=verbose
...

{"Customer":{"__metadata":{"type":"SP.Taxonomy.TaxonomyFieldValue"},"Label":"1","TermGuid":"47081a2a-c78d-495c-bea9-e1ba8522e881","WssId":"-1"},"__metadata":{"type":"SP.Data.ClientsListItem"}}

You need to plug four values into the JSON payload:
  • The name of the managed metadata field (Customer in this example). 
  • The Label value. This can either be the string-based term label or an integer-based lookup value. If you used the REST API to get the term details from an existing list item, you'll have an integer value.
  • The TermGuid value. 
  • The WssId value. You can safely set this value to -1. SharePoint will resolve the term correctly from the Label and TermGuid values.
You could do this with a Call HTTP Web Service activity in SharePoint Designer, but structuring the data would be ugly and laborious. A more elegant solution is to create a couple of custom activities in Visual Studio that you can reuse in multiple SharePoint Designer workflows. In part 2 I'll show you how to create a custom activity to get managed metadata field values, and in part 3 I'll show you how to create a custom activity to set managed metadata field values.

Comments

  1. Thanks a lot. It's helpful, but it does not work for a multi value metadata taxonomy field !

    ReplyDelete

Post a Comment

Popular posts from this blog

Server-side activities have been updated

The target principal name is incorrect. Cannot generate SSPI context.

Custom Workflow Activity for Creating a SharePoint Site