SharePoint 2010 : Setting Default Value of Managed Metadata Column for a Completely New Site Collection

Introduction

"Managed metadata is a hierarchical collection of centrally managed terms that can be defined, and then used as attributes for items in SharePoint Server 2010." [SharePoint]

"A Managed Metadata column is a new column type that can be added to lists, libraries, or content types to enable site users to select values from a specific term set of managed terms and apply these values to their content." [Office]

This article will explain how to set default value of managed metadata column programmatically for a completely new site with a term not used prior to this in the entire site collection.

Here is a sample structure of term set and term, where we will set the term “ABC” as default value for the column. The term “ABC” has not been used previously in the entire site collection.

The Format

Managed metadata field or TaxonomyFieldType is similar to a lookup field and requires a specific format for setting the value.

ID;#Termlabel|GUID

 ID : WSSID   [ Explained later in this article]

Termlabel: TermName

GUID : TermGuid
 

The Code

      TermSet termSet = null;        Term term = null;        TaxonomySession currentSession = new TaxonomySession(site);        var termStore = currentSession.TermStores["ManagedMetadataService"];        var group = termStore.Groups["Companies"];                      termSet = group.TermSets["IT"];                         
term = termSet.Terms["ABC"];        int[] wssId = TaxonomyField.GetWssIdsOfTerm(site, termStore.Id, termSet.Id, term.Id, false, 1);       TaxonomyField field = list.Fields["FiledName"] as TaxonomyField;
                            
field.SspId = termSet.TermStore.Id;        field.TermSetId = termSet.Id;        field.TargetTemplate = string.Empty;       field.AnchorId = Guid.Empty;       field.DefaultValue =         wssId[0].ToString() + ";#" + term.Name + "|" + term.Id.ToString().ToLower();                       
field.Update();         

This code works well in most of the site collection, but for one site collection it did not work. So I started investigation and found that WSS Id value is null in this case.

Exploring further, it was found that there is a hidden list called “TaxonomyHiddenList”.

URL – /lists/taxonomyhiddenlist

Description of Hidden List and WSSID

"For each site collection using the term store, SharePoint creates a hidden list. In this hidden list SharePoint stores information about the managed terms IN USE in the site collection. It’s important to note that just creating the term does not mean an entry will be created in this hidden list, only when the term is assigned to an item or document, then a list entry gets created. The WSSID is the list item GUID in the hidden list." [stackexchange.com]

Here is the screen grab which shows properties of the keyword in the hiddenlist.

  So this method internally queries taxonomy hidden list and gets the data associated with the keyword.

int[] wssId = TaxonomyField.GetWssIdsOfTerm(site, termStore.Id, termSet.Id, term.Id, false, 1);

But in our case we have created a fresh/new site so this hidden list does not contain any data since not a single keyword is used in the site. So what is the workaround for this?

Well, after exploring the solution to this problem, I found that we can add keyword to this hidden list and then we can get WSS Id associated with keyword.

The method below adds entry in hidden list and returns associated WSSID using reflection.

 

     public static int AddGuidToHiddenList(SPSite newsite, Term newTerm, bool isKeywordField){             int id = -1;                    try                    {                     Type txFieldType = typeof(TaxonomyField);                   
              MethodInfo methodInfoTaxonomyGuid = txFieldType.GetMethod("AddTaxonomyGuidToWss",                                                                 BindingFlags.NonPublic | BindingFlags.Static,null,                                                        new Type[3] { 
                                      typeof(SPSite), 
                                      typeof(Term), 
                                      typeof(bool) },                                                                             null                                                           );                                     if (methodInfoTaxonomyGuid != null)     
                    {    
                            id = (int)methodInfoTaxonomyGuid.Invoke(null,
                                     new object[3] { newsite, newTerm, isKeywordField });                        }                         return id;        
            }     
            catch (Exception ex)       
            {             
          return id;        
            }     }        

So now we can use this function in our code and make it work.

The Final Code

TermSet termSet =null;Term term =null;
TaxonomySession currentSession =new TaxonomySession(site);var termStore = currentSession.TermStores["ManagedMetadataService"];var group = termStore.Groups["Companies"];                   
termSet = group.TermSets["IT"];                                term = termSet.Terms["ABC"];int[] wssId =TaxonomyField.GetWssIdsOfTerm(site, termStore.Id, termSet.Id, term.Id,false, 1);TaxonomyField field = list.Fields["FiledName"]as TaxonomyField;                                 
field.SspId = termSet.TermStore.Id;field.TermSetId = termSet.Id;field.TargetTemplate = string.Empty;field.AnchorId = Guid.Empty;if (wssId.Length > 0){field.DefaultValue = wssId[0].ToString() +";#" + term.Name + "|" + term.Id.ToString().ToLower();                  }Else{ int id = AddGuidToHiddenList(site, term,false);                                          field.DefaultValue = id.ToString() +";#" + term.Name + "|" + term.Id.ToString().ToLower();                      }field.Update();

 

 

This will now add a default value in the taxonomy column and can be seen as below: