Setting Managed Metadata Column Default Value

Monday, April 28, 2014

2

In this post I'll go over programmatically setting the default value on a taxonomy column.  This turns out to be a bit trickier than one would expect.

TaxonomyField.DefaultValue expects a string in the format <WssId>;#<TermLabel>|<TermGuid>. TermLabel and TermGuild are easy to find, but what about WssId?

If you already know about the TaxonomyHiddenList and WssId, go ahead and skip to the next paragraph. Every site that works with Managed Metadata has a hidden list called, aptly, TaxonomyHiddenList. This serves as a local cache, and all term references on the site actually point to items in this hidden list. WssID refers to a term’s ID in this list. It is initially empty, and terms are added the first time they’re actually used on the site.

In most situations, we do not have to worry about the WssID. When adding a list item with a taxonomy field, setting WssID to -1 tells SharePoint to resolve the WssID if the term exists in TaxonomyHiddenList, or otherwise add it.

Unfortunately, this does not work when setting a field’s default value. The -1 WssId will simply be saved as the default value. Note that setting DefaultValue with an invalid WssID will not cause an exception, and the default value still shows up in the column settings UI. However, when you actually create a new list item, the default value will not be set.

We can try to retrieve WssId from TaxonomyHiddenList, but if the term hasn’t been used on the site before, there will be no WssID. SharePoint does not expose any method to explicitly add a term to the hidden list.

The solution is to create a dummy list item, and call SetFieldValue with the term. You do NOT have to actually save the dummy item by calling Update() on it. Simply calling SetFieldValue triggers a SharePoint internal “TouchAllTaxonomyColumns” method on the field, which populates the hidden list if needed.

Finally, GetValidatedString returns the complete string that DefaultValue expects.

$web = Get-SPWeb -Identity http://sharepointificate.com

# Get Taxonomy column

$list = $web.Lists["Posts"]
$taxField = $list.Fields["Label"] -as 
              [Microsoft.SharePoint.Taxonomy.TaxonomyField];

# Get term

$termStoreId = taxField.SspId;
$termSession = Get-SPTaxonomySession -Site $list.ParentWeb.Site;
$termStore =  $termSession.TermStores[$termStoreId];
$termSet = $termStore.GetTermSet( $taxField.TermSetId );
$terms = $termSet.GetTerms( "SharePoint", $false );
$term = $terms[0];

# Use the term in a dummy item to ensure that is added to the site's
# HiddenTaxonomyList and has a WssId. Do NOT call Update() on
# the item-- we don't actually want to add it.  Simply calling SetFieldValue
# will force SP to initialize the hidden list entry.

$newItem = $list.Items.Add();
$taxField.SetFieldValue( $newItem, $term );

# Retrieve term string from dummy item, 
# in form of <wssid>;#<termlabel>|<termguid>

$value = $taxField.GetValidatedString( $newItem[$taxField.Id] );

# Set default value and save

$taxField.DefaultValue = $value;
$taxField.Update(); 


2 comments:

For 24 hours this issue was running like a loop in my head. I was using 1033 for Wss ID. It does not give any error and that was most confusing part to find out whats going on.

You saved a lot of time. Thanks for posting this...

Has anyone come across any methods/events that force an update on existing TaxonomyHiddenList items?

Post a Comment