Tuesday, January 5, 2010

Getting metadata terms for a SharePoint 2010 Field through code

Technorati Tags:

SharePoint 2010 contains a new field type named "Managed Metadata”. This type of field enables users to tag content with terms that are created at the site level or at the enterprise level. When defining the field on a list or a site you are asked to point to a particular TermSet. You can read more about this process here at this link:

Managed Metadata Overview

However, this post is about using the SharePoint 2010 object model to retrieve the TermSet that a “Managed Metadata” field is linked to. So if you had a custom web part or another application that you wished to emulate the same term picker used in SharePoint 2010 UI then this code could help you. The returned TermSet is a hierarchical list of terms. So the returned TermSet contains a Terms property containing a TermCollection  of Term objects. Each Term object also contains a Terms property containing a TermCollection. In the SharePoint UI users are able to either use the term or click on the term to expand it and select from the child terms. So you can use the returned TermSet to recursively populate your own hierarchical UI structure like a treeview control in silverlight or wpf. 

The example code takes a string in url format of the site collection that the field resides in. Secondly it takes the list name that the field resides in and finally it takes the internal name of the “Managed Metadata” field. The key is to get the corresponding TaxonomySession object for the site or site collection. Once that is done you can use linq to query the fields collection of the list and pull out the “Managed Metadata” field. The strange thing about “Managed Metadata” fields is that the SPFieldType is set to “Invalid”. A TaxonomyField type is not listed as a valid SPFieldType like Text or Choice, so I was not able to use the SPFieldType enumeration in the linq query but had to do a string comparison on the TypeAsString property. Possibly this will be different in the release candidate.

Code:

 

public static TermSet GetTermsForMetadataField(string siteUrl, string listName, string internalName)
{
TermSet termSet = null;

using (SPSite site = new SPSite(siteUrl))
{
TaxonomySession txs= new TaxonomySession(site);

using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists[listName];

TaxonomyField tf = (from f in list.Fields.OfType<SPField>()
where string.CompareOrdinal(f.InternalName,internalName)== 0
&& string.CompareOrdinal(f.TypeAsString, "TaxonomyFieldType") == 0
select f).Distinct().First() as TaxonomyField;

if (tf != null)
termSet = txs.DefaultSiteCollectionTermStore.GetTermSet (tf.TermSetId);

}

}

return termSet;

}