In this post I’m going to show you how to bypass a limitation of SharePoint Designer 2013 workflows that prevents us from directly updating a managed metadata field.
The proposed solution works for both SharePoint 2013 On Premises and Online (Office 365) and uses only the SharePoint Designer 2013 built-in actions.
Scenario
We have a custom list item with a managed metadata (taxonomy) field in it. We need to update the taxonomy field using a SharePoint Designer 2013 workflow.
Problem
When you try to update a managed metadata field through the “Update List Item” action a BadRequest error occurs with the following message:
An unexpected ‘PrimitiveValue’ node was found when reading from the JSON reader. A ‘StartObject’ node was expected.
This happens because SharePoint is expecting a complex type. However, any value you supply through a built-in list action in SharePoint Designer gets wrapped in quote marks and treated as a string literal…
So, how to get around this limitation?
Solution
When you add a taxonomy field in SharePoint, you are really adding two fields:
- The first one is the visible field you see and edit
- The second one is a hidden note field which holds the values for its associated field as plain text
Let’s say you add a taxonomy field called “TaxonomyField”, SharePoint will automatically add a note field called “TaxonomyField_0”.
Here is the solution to all our problems:
If we update the hidden field “TaxonomyField _0” with a well formatted text value then its associated taxonomy field gets updated as well.
Great!
We can update a hidden field in a SharePoint Designer 2013 workflow only using REST with the “Call HTTP Web Service” action.
So, all we need to do now is to get the internal name of our hidden field and set its value with a REST call using the format
Term1Name|Term1Guid
For a multi value managed metadata field we need to separate the entries with a semicolon, like this:
Term1Name|Term1Guid;Term2Name|Term2Guid
Let’s see how to do this in more detail…
Steps
1. Get the hidden field internal name
Finding the internal (static) name of the hidden field can be done by using the SharePoint REST API via a browser using a URL like this
https://site/_api/web/lists/getbytitle('listtitle')/fields
In the example below the static name for our hidden field is “l4ea604b343942df935ba60a0e9dd7ad”.
2. Get the term name and guid
In the Term Store Management Tool for your site (Site Settings > Site Administration > Term Store Management) find the term you want to use to update the taxonomy field and get its name and guid.
In the example below the name and guid of our term are respectively “Term1” and “6dfad373-fc10-4a84-b83f-efa262c18275”.
3. Get the list item type
To get the list item type we need to use the SharePoint REST API via a browser again using a URL like this
https://site/_api/web/lists/getbytitle('listtitle')
Then we must get the value for the “d:ListItemEntityTypeFullName” element.
In the example below the list item type is “SP.Data.TaxonomyListListItem”.
4. Create the headers dictionary
Now we have all the information we need to start working with our SharePoint Designer 2013 workflow.
First of all we must build a dictionary to store some headers, specifically the following ones:
Accept: application/json;odata=verbose Content-Type: application/json;odata=verbose Content-Length: <length of post body> X-HTTP-Method: MERGE If-Match: *
5. Create the metadata dictionary
Next we need to create a dictionary to store our metadata.
This dictionary will only contain one entry for the list item type we’ve obtained previously:
type: SP.Data.TaxonomyListListItem
6. Create the data dictionary
Next, we need one more dictionary that will contain our request data.
The dictionary must have an entry with key “__metadata” (note the double underscore before the “metadata” string) with its value set to the previously created metadata dictionary.
We also need to add another entry in the data dictionary with its key set to the internal name of our hidden field and its value having the format “TermName|TermGuid”.
__metadata: <metadata dictionary> l4ea604b343942df935ba60a0e9dd7ad: Term1|6dfad373-fc10-4a84-b83f-efa262c18275
7. Call the SharePoint REST service
Finally, we are ready to call the SharePoint REST service to update our taxonomy field. To do this we need to insert the “Call HTTP Web Service” action in our workflow.
The action URL must be constructed dynamically to point to the current item like this
https://site/_api/web/lists/getbytitle('listtitle')/items(n)
The action verb must be set to POST.
Then we need to set the request headers to the headers dictionary and the request content to the data dictionary.
Conclusion
This is how the complete workflow should look like:
Now we can publish and run it. Once it is over we’ll have our taxonomy field correctly updated.