I have seen many requests on how to set a managed metadata field using the client object model. Most of the questions revolve around the fact that many remote applications do not have access to the required information for setting a managed metadata field. A managed metadata field contains a term and the term is stored with three pieces of information. The first piece is the ID that represents the ID of the term in the local site collection’s TaxonomyHiddentList. The second piece is the term value itself which is usually the label the user tagged it with. The final piece is the term’s ID which is in the form of a GUID. This represents the unique ID of the term in the term store of the site collection. This term store is published from the associated metadata service application. Here is an example of how the value is stored for a term named escalade.
Remote applications have the term they want to add but do not have the ID to the TaxonomyHiddenList list and the unique ID of the term. The ID to the term in the TaxonomyHiddenLIst can be ignored by just using –1 in its place. However, you must have the ID of the term. One solution was to query the TaxonomyHiddenList list for it. Unfortunately, the term is only put there after it has been used in the site collection. This is done for performance reasons. In order to set the managed metadata field from CSOM you must use the TaxonomyClientService web service to obtain the ID of the term. In this post I will show you how to use both the managed CSOM and the TaxonomyClientService web service to set the managed metadata field, also, I will show you how to do this with a multi-valued managed metadata field.
Getting all the information
Setting a managed metadata field requires multiple steps in order to gather the required information.
- Get the managed metadata field of the list.
- Get the shared service ID (GUID of the metadata service application) and the term set ID from the field’s schema.
- Get the set of terms for the term set from the TaxonomyClientService web service.
- Parse the returned xml and obtain the term ID for the term you are going to use.
Four simple steps. I wish they were. The biggest problem is understanding how to parse the returned xml from the GetTermSets method of the TaxonomyClientService. The xml schema has no discernable reason or order to it. The schema has arbitrary attribute names. Below is an example:
The term set I am using in this example is called Cadillac and contains a group of terms for different models of Cadillac cars. Each term is contained in a “T “ node and the “a9” attribute represents the ID of the term. The term label is contained in the child “TL” node and the label is denoted by the “a32” attribute. The code below calls the TaxonomyClientService and searches for term using the term label sent in as an argument.
public static string GetTermInfo(string siteUrl, Field field, string term, ref string textField)
Setting all the information
The code below puts it all together by setting the required information. In the case of using the client object model you must set two fields for the update to be successful. Every managed metadata field has a corresponding hidden taxonomy text field. The GetTermInfo method returns the ID of this hidden field so the code can also update its value. This field holds the same information as the managed metadata field but is used for internal purposes. Notice also the code checks to see if the current value supports multiple values by checking if the type can be assigned to an object array. If it can then you must add terms to a list an convert the values back to an array. You must also append all the values with a semi-colon for the hidden taxonomy field. Finally you will only need to set the ID value to a –1 and the server side code will look it up for you. So there are no extra calls needed to look up the value from the TaxonomyHiddentList.
public static void SetManagedMetaDataField_ClientOM(string siteUrl,string listName, string itemID, string fieldName, string term)
In summary this example will take the term label, site URL, managed metadata field name, list name and the ID of the item you want to update. It will use this information to update the managed metadata field with the term. You can use this example to build more sophisticated scenarios where you may want to replace a particular term with another if the column holds multiple values. The taxonomy web service has methods to lookup terms based on a culture for multi-lingual cases, and the ability to search for terms where there are more than one term store. Your best bet is to build a term picker using the information from the taxonomy web service. In this case users would pick from a dialog what term they want to tag a value with. Using a term picker the term ID would already be available to use and would allow the user to easily navigate complicated term stores.
I hope this helps in understanding all the extra steps that must be taken when setting managed metadata from remote applications. Hopefully, this will become much easier in future versions of SharePoint.