Jan 07 2012

Setting a Default Value for a Managed Metadata Column

Some of the cool new features of SharePoint 2010 are the features related to the Managed Metadata Service Application. A lot of these features were things that companies have been asking for for a while now. For instance the ability to manage hierarchical metadata in a central location, instead of having to create choice lists in every site collection is something that is probably going to be used in the document management solutions of most larger companies. This automatically means that it will be used in a lot of custom solutions as well. At first glance this doesn’t seem like a problem. After all, why would using a managed metadata (site) column in your custom solution be any different then using any other (site) column. To be honest, I’m not sure about the why, although I could think of a few reasons, but using managed metadata columns in a custom solution is vastly different than using any other column.

Personally I had to set a default value of a Managed Metadata Site Column from my custom web part. The step is to add a taxonomy field to my web part, so a user can select a default term. The way to do this is by adding a TaxonomyWebTaggingControl to the web part and setting its properties. We use the current site to setup a session to the Managed Metadata Service Application. Internally the Web Application of the current site is used for this, as Service Applications are linked to Web Applications by Service Application Proxies. Once we’ve got a TaxonomySession we can choose whether we want to get all term stores (TaxonomySession.TermStores), the term store that is selected as the default term store for keywords (TaxomomySession.DefaultKeywordsTermStore), or the default term store for the site collection (TaxonomySession.DefaultSiteCollectionTermStore). Once we’ve got a term store we’ve got to make sure that it’s online and when it is we can request the term group and the term set that we want to use for the site column from it. To assign a term store to a TaxonomyWebTaggingControl we have to assign the term store guid as a string to the SSPList property.

   1: SPSite currentSite = SPContext.Current.Site;
   2: // Instantiates a taxonomy session for the current site
   3: TaxonomySession taxonomySession = new TaxonomySession(currentSite);
   4: TermStore termStore = taxonomySession.DefaultKeywordsTermStore;
   5: if (termStore.IsOnline)
   6: {
   7:     termGroup = termStore.Groups["MyTaxonomyGroup"];
   8:     termSet = termGroup.TermSets["MyTermSet for instance Country"];
   9: }
  10: TaxonomyWebTaggingControl taggingControl = new TaxonomyWebTaggingControl();
  11: taggingControl.SSPList = termStore.Id.ToString();
  12: taggingControl.GroupId = termGroup.Id;
  13: taggingControl.TermSetList = termSet.Id.ToString();
  14: // This controls whether you can add new terms to the term set
  15: taggingControl.AllowFillIn = false;
  16: // This controls whether unresolved terms will just be added to the termset or not
  17: taggingControl.IsAddTerms = false;
  18: // This setting allows you to browse the term set
  19: taggingControl.IsDisplayPickerButton = true;
  20: // This setting enables/disables validation highlighting
  21: taggingControl.IsIgnoreFormatting = false;
  22: taggingControl.IsIncludeDeprecated = false;
  23: taggingControl.IsIncludeUnavailable = false;
  24: // This setting modifies what is stored/returned from the control
  25: // if you want the GUIDS of parent terms then set this to true
  26: taggingControl.IsIncludePathData = true;
  27: // This setting will include term set name resolution as well if set
  28: taggingControl.IsIncludeTermSetName = false;
  29: taggingControl.ID = "MyCustomMetadataControl";
  30:  


Now a user can select a default value. By after a user clicks a button we can store the value the user selected as the default value of the site column. Be aware that if you let non-Site Owner users select a default value that you will have to use impersonation as only Site Owners can set default values for site columns.

The way we have to save a default value for a taxomony column is very specific. You can leave some of these steps out and it will seem like it works. If you go into the Site Column management user interface via the Site Settings page in your site you will probably see that a default value has been selected and it will seem like SharePoint resolves the value without a problem. However if you are using the column in a document library and you are trying to create a new document in Word 2010 the document information panel will indicate that the default value is a value that doesn’t exist in the term store. Pretty tricky that!

The value of a Managed Metadata Column is build op from three parts:

  • The Id of the term as it is stored in the TaxonomyHiddenList . The TaxonomyHiddenList caches all terms from the term store in the site collection. The link is referred to as the WssId.
  • The label of the term
  • The guid of the term

The format of the value looks like this:
<WssId>;#<TermLabel>|<TermGuid>

In order to set a value for a TaxonomyField we have to use a TaxnomomyFieldValue.
We can use the PopulateFromLabelGuidPair method to convert the Text value of the TaxonomyWebTaggingControl on our web part into a valid Label/Guid pair.
We are setting the WssId to –1. We could try to retrieve the actual Id of the term from the TaxonomyHiddenList by using the TaxonomyField.GetWssIdsOfTerm method, but if we set it to –1 SharePoint will resolve it for us and will even add the term to the TaxonomyHiddenList if it’s not already in there.
Another oddifity is that we have to convert the guid of the selected term to a lower case guid, or the Document Information Panel in Office 2010 won’t recognize the term.

1: TaxonomyField taxonomyField = SPContext.Current.Site.RootWeb.Fields.
GetFieldByInternalName(["MyManagedMetadataSiteColumn"]) as TaxonomyField;

   2: TaxonomyFieldValue defaultValue = new TaxonomyFieldValue(taxonomyField);
   3: try
   4: {
   5:     defaultValue.PopulateFromLabelGuidPair(taggingControl.Text);
   6:     defaultValue.WssId = -1;
   7:     // GUID should be stored lowercase, otherwise it will not work in Office 2010
   8:     defaultValue.TermGuid = defaultValue.TermGuid.ToLower();
   9:     // Set the selected default value for the site column
  10:     taxonomyField.DefaultValue = defaultValue.ValidatedString;
  11:  
  12: }
  13: catch
  14: {
  15:     ErrorMessage.Text = "Creating a new term is not allowed, please select an existing term.";
  16:     taxonomyField.DefaultValue = String.Empty;
  17: }
  18:  
  19: taxonomyField.UserCreated = false;
  20: taxonomyField.Update(true);


I think I would still be looking for a solution for this if it wasn’t for Donald Hessing’s answer on the SharePoint Forums, so thanks Donald!

I hope this post will save others some time, just like Donald’s post saved me some time.