Managed metadata is a hierarchical collection of centrally managed terms that you can define and then use as attributes for items in Microsoft SharePoint Server 2010. Managed terms can act as sources of data for columns in libraries or lists. To manage the taxonomy column by using the server object model, there are APIs available under the Microsoft.SharePoint.Taxonomy namespace. However, handling managed metadata columns by using the client object model requires a different strategy.

Managed Metadata Columns

To work with managed metadata columns by using the SharePoint client object model, it helps to have an understanding of how managed metadata columns store values in lists. Consider the following details:
Managed Metadata Columns are Derived from SPFieldLookup
TaxonomyFieldValue has a WSS identifier that is the LookupId property of the term in theTaxonomyHiddenList list. The TaxonomyHiddenList list can be viewed by navigating to/Lists/TaxonomyHiddenList/AllItems.aspx. This list contains the details of all of the terms that are used in any managed metadata column.
For Each Managed Metadata Column, the List has Two Columns
For every metadata column, there are two columns in the list. One column is created with a field name of type Taxonomy Field and other column is created with the name in format fieldnameTaxHTField0 of type Note. Details of the taxonomy hidden column (fieldnameTaxHTField0) can be found in the XML of the taxonomy field. The XML of a taxonomy field is similar to the following. The TextField highlighted in yellow contains the GUID of the hidden column.
<Field Type="TaxonomyFieldType" DisplayName="Language" List="{df9afe98-76ae-45ff-9367-e8c94fgb72c2}" WebId="e6b4333c-617b-4875-bd5d-10e745d5caa3" ShowField="Term1033" Required="FALSE" EnforceUniqueValues="FALSE" ID="{10c90ea3-94e8-453f-b046-ccf3d7b82c3b}" SourceID="{8b16fadf-a200-429d-9f77-b218863efdba}" StaticName="Language" Name="Language" ColName="int1" RowOrdinal="0" Version="1">
        <Default />
        <Customization>
            <ArrayOfProperty>
                - <Property>
                    <Name>SspId</Name>
                    <Value xmlns:q1="
http://www.w3.org/2001/XMLSchema" p4:type="q1:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">a3c8fc5c-a9ca-46c5-b0c4-fd3f1d1b82f3</Value>
                </Property>
                - <Property>
                    <Name>GroupId</Name>
                </Property>
                - <Property>
                    <Name>TermSetId</Name>
                    <Value xmlns:q2="
http://www.w3.org/2001/XMLSchema" p4:type="q2:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">23cc4396-6de3-47a7-97a6-111675414126</Value>
                </Property>
                - <Property>
                    <Name>AnchorId</Name>
                    <Value xmlns:q3="
http://www.w3.org/2001/XMLSchema" p4:type="q3:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">00000000-0000-0000-0000-000000000000</Value>
                </Property>
                - <Property>
                    <Name>UserCreated</Name>
                    <Value xmlns:q4="
http://www.w3.org/2001/XMLSchema" p4:type="q4:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">false</Value>
                </Property>
                - <Property>
                    <Name>Open</Name>
                    <Value xmlns:q5="
http://www.w3.org/2001/XMLSchema" p4:type="q5:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">false</Value>
                </Property>
                - <Property>
                    
<Name>TextField</Name>
                    <Value xmlns:q6="
http://www.w3.org/2001/XMLSchema" p4:type="q6:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">{6a8b96d5-78a1-4e98-875f-52bcd3ebd95a}</Value>
                </Property>
                - <Property>
                    <Name>IsPathRendered</Name>
                    <Value xmlns:q7="
http://www.w3.org/2001/XMLSchema" p4:type="q7:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">false</Value>
                </Property>
                - <Property>
                    <Name>IsKeyword</Name>
                    <Value xmlns:q8="
http://www.w3.org/2001/XMLSchema" p4:type="q8:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">false</Value>
                </Property>
                - <Property>
                    <Name>TargetTemplate</Name>
                </Property>
                - <Property>
                    <Name>CreateValuesInEditForm</Name>
                    <Value xmlns:q9="
http://www.w3.org/2001/XMLSchema" p4:type="q9:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">false</Value>
                </Property>
                - <Property>
                    <Name>FilterAssemblyStrongName</Name>
                    <Value xmlns:q10="
http://www.w3.org/2001/XMLSchema" p4:type="q10:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">Microsoft.SharePoint.Taxonomy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Value>
                </Property>
                - <Property>
                    <Name>FilterClassName</Name>
                    <Value xmlns:q11="
http://www.w3.org/2001/XMLSchema" p4:type="q11:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">Microsoft.SharePoint.Taxonomy.TaxonomyField</Value>
                </Property>
                - <Property>
                    <Name>FilterMethodName</Name>
                    <Value xmlns:q12="
http://www.w3.org/2001/XMLSchema" p4:type="q12:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">GetFilteringHtml</Value>
                </Property>
                - <Property>
                    <Name>FilterJavascriptProperty</Name>
                    <Value xmlns:q13="
http://www.w3.org/2001/XMLSchema" p4:type="q13:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">FilteringJavascript</Value>
                </Property>
            </ArrayOfProperty>
        </Customization>
    </Field>

As stated previously, the the TextField is of type Note. The XML for the TextField is similar to the following:
<Field Type="Note" DisplayName="Language_0" StaticName="LanguageTaxHTField0" Name="LanguageTaxHTField0" ID="{6a8b96d5-78a1-4e98-875f-52bcd3ebd95a}" ShowInViewForms="FALSE" Required="FALSE" Hidden="TRUE" CanToggleHidden="TRUE" SourceID="{8b13fadf-a200-429d-9f77-b218843efdba}" ColName="ntext2" RowOrdinal="0" />
Taxonomy Field Data
The data in taxonomy fields is stored in the following format:
Sample Column NameColumn TypeSample ValueFormat of Saved Data
LanguageTaxonomy Field2;# EnglishWSS Id ;# Name of Term
LanguageTaxHTField0NoteEnglish | c61d9028-824f-446e-9389-eb9515813a42Name of Term | GUID of Term
The WSS identifier is a 32-bit integer that uniquely identifies list’s list item containing the taxonomy field. This property behaves similarly to the LookupId property and is used as the lookup identifier on theTaxonomyHiddenList list.

Updating the Manage Metadata Column by Using the Client Object Model

To update the taxonomy column, the two associated columns need to be updated with appropriate values.
To update those columns, perform the following steps:
1. Find the WSS identifier of the term that needs to be set as the value. You can use the following code to get the value of WSS identifier of the term:
Microsoft.SharePoint.Client.List taxonomyList = clientContext.Site.RootWeb.Lists.GetByTitle("TaxonomyHiddenList");
CamlQuery camlQueryForTerm = new CamlQuery();
                    camlQueryForTerm.ViewXml = @"<View>
                          <Query>
                            <Where>
                              <Eq>
                                <FieldRef Name='IdForTerm'/>
                                <Value Type='Text'>" + TermGuidId + @"</Value>
                              </Eq>
                            </Where>
                          </Query>
                        </View>";

Microsoft.SharePoint.Client.ListItemCollection termItems = taxonomyList.GetItems(camlQueryForTerm);
                    clientContext.Load(termItems);
                    clientContext.ExecuteQuery();

TermGuidId is the GUID of the term to be set as the value.
2. If there is an entry in the TaxonomyHiddenList list for the given term then the values can be updated by using the WSS identifier. If the TaxonomyHiddenList list does not contain an entry for the given term then the scenario is different.
If there is no entry for the term then the WSS identifier must be set as -1. The following table describes the sample format in which to save the data:
Column TypeFormat (term exists in TaxonomyHiddenList list)Format (term does not exist in TaxonomyHiddenList list)
Taxonomy fieldWSS Id ;# Name of term-1 ;# Name of term | GUID of term
Note fieldName of term | GUID of termName of term | GUID of term
The following is the code to update the value based on the CAML query results from step 1:
if(termItems.Count > 0)
{
   Microsoft.SharePoint.Client.ListItem termItem = termItems[0];
   splistItem[ColumnName] = termItem["ID"] + ";#English";                              
   splistItem[TextColumnName] = "English |c61d9028-824f-446e-9389-eb9515813a42";
}
else
{
   splistItem[ColumnName] = "-1;#English|c61d9028-824f-446e-9389-eb9515813a42";                             
   splistItem[TextColumnName] = "English|c61d9028-824f-446e-9389-eb9515813a42";
}
splistItem.Update();
context.ExecuteQuery(); 

For metadata columns with multiple values, the values should be separated by ;#. For example, more than one value can be saved in the format given below, based on whether the terms already exist in theTaxonomyHiddenList list.
  • If there is entry in the TaxonomyHiddenList list, use the following:
splistItem[ColumnName] = "2;#English;#3;#French";
splistItem[TextColumnName] = "English|c61d9028-824f-446e-9389-eb9515813a42;#
French|de1d9028-824f-556e-9389-ac9515813a56";

  • If there is no entry in the TaxonomyHiddenList list, use the following:
splistItem[ColumnName] = "-1;#English|c61d9028-824f-446e-9389-eb9515813a42;#
-1;#French|de1d9028-824f-556e-9389-ac9515813a56";
splistItem[TextColumnName]= English|c61d9028-824f-446e-9389-eb9515813a42;# French|de1d9028-824f-556e-9389-ac9515813a56";

In this post, I discussed how managed metadata columns can be handled by using the client object model to update the different columns with appropriate values.