In this series of posts I will talk about using Taxonomy fields in SharePoint 2010 development. They are a funky bunch and don´t work quite as you would expect. I will talk about the following subjects:
Introduction
Part I: Declaration and initialization
Part II: Using taxonomyfields programmatically (you are reading it!)
Part III: Searching taxonomy fields
The other part will be online in the next couple of weeks.
In this part I will talk about using the TaxonomyFields in your code. Read part I of my series to read about how to declare a TaxonomyField and create a contenttype containg the field.
Creating the basis
If I create a custom list on my site called TaxList and add the contenttype I’ve created in part 1 of this series to the Content Types of the list, I get a list with the following settings:

Now I add an item with the title “check” to the list using MyCustomContenttype and select a value from the termstore to inhabit my TaxonomyField. The resulting list looks like this (I’ve changed the view to show the TaxonomyField):

All pretty basic stuff so far. The reason I’m showing you this is to set the basis for the code to follow. In this code I will use the created list to show you how to read and write values to and from a TaxonomyField programmatically.
Working with TaxonomyFields programmatically
So what is actually stored in the field? Reading the contents of the field in the “standard” way goes something like this (I’m printing the result to a Label within a simple visual webpart that contains only a label):
// get the sitecollection from context
SPSite site = SPContext.Current.Site;
// get the list
SPList lstTaxList = site.RootWeb.Lists.TryGetList("TaxList");
if (lstTaxList != null)
{
// Try to find the item I want
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>check</Value></Eq></Where>";
SPListItemCollection foundItems = lstTaxList.GetItems(query);
// did we find something?
if (foundItems.Count > 0)
{
// print the contents of the taxonomyfield of the first item found
lblFieldViewer.Text = foundItems[0][new Guid("8D0458C1-0FB7-4981-BEE1-52D0DF01895C")].ToString();
}
}
The result looks like this:
Corporate Staf|0cdf313f-92e2-472b-bdb9-73a25d200cf2
As you see the field holds the name and the guid of the term seperated by a pipe symbol.
Reading data from a TaxonomyField programmatically
So how do we get a useful value from the field? For this the classes TaxonomyFieldValue and TaxonomyFieldValueCollection exist. We simply cast the contents of the field to a TaxonomyFieldValueCollection and we can access the individual TaxonomyFieldValues and their properties TermGuid and Label. I’ve replaced the last line of the previous code-sample to the following:
// load the contents of the taxonomyfield of the first item found
TaxonomyFieldValueCollection coll = (TaxonomyFieldValueCollection)foundItems[0][new Guid(TAXONOMYFIELDID)];
StringBuilder sb = new StringBuilder();
foreach (TaxonomyFieldValue val in coll)
{
// get termguid
string termGuid = val.TermGuid;
// get label
string label = val.Label;
// build the string
sb.AppendLine(string.Format("GUID: {0}, Label: {1}", termGuid, label));
}
lblFieldViewer.Text = sb.ToString();
Since we are able to get the term’s Guid, we can also get the Term object from the TermStore in the following way:
Update 4th of November 2011: Be sure to read my follow-up post to learn how to improve this code to make it ready for a production environment!
// load the contents of the taxonomyfield of the first item found
TaxonomyFieldValueCollection coll = (TaxonomyFieldValueCollection)foundItems[0][new Guid(TAXONOMYFIELDID)];
StringBuilder sb = new StringBuilder();
// Open a taxonomysession and get the associated termstore from it
TaxonomySession session = new TaxonomySession(site);
TermStore termStore = session.TermStores[0];
foreach (TaxonomyFieldValue val in coll)
{
// get termguid
string termGuid = val.TermGuid;
// get label
string label = val.Label;
// get the Term
Term term = termStore.GetTerm(new Guid(termGuid));
// build the string
sb.AppendLine(string.Format("GUID: {0}, Label: {1}", term.Id, term.Name));
}
lblFieldViewer.Text = sb.ToString();
Using SPQuery and TaxonomyFields
So how do I look up items in a list using SPQuery with a TaxonomyField in the WHERE clause? Remember that a TaxonomyField is nothing more than a lookup field. Its possible values are stored in the TaxonomyHiddenList in the site collection. If you store a Term in a TaxonomyField in a sitecollection for the first time, the Term is automagicly stored in the TaxonomyHiddenList in the sitecollection. This way Sharepoint does not have to access the TermStore everytime you use that Term. To find the Id of the record in the TaxonomyHiddenList the static methods TaxonomyField.GetWssIdsOfTerm or TaxonomyField.GetWssIdsOfKeywordTerm can be used as the following example shows:
Update 4th of November 2011: Be sure to read my follow-up post to learn how to improve this code to make it ready for a production environment!
private SPListItemCollection GetItemsByTerm(Term term, SPList list)
{
// init some vars
SPListItemCollection items = null;
SPSite site = SPContext.Current.Site;
// set up the TaxonomySession
TaxonomySession session = new TaxonomySession(site);
// get the default termstore
TermStore termStore = session.TermStores[0];
// If no wssid is found, the term is not used yet in the sitecollection, so no items exist using the term
int[] wssIds = TaxonomyField.GetWssIdsOfTerm(SPContext.Current.Site, termStore.Id, term.TermSet.Id, term.Id, false, 1);
if (wssIds.Length > 0)
{
// a TaxonomyField is a lookupfield. Constructing the SPQuery
SPQuery query = new SPQuery();
query.Query =
String.Format("<Where><Eq><FieldRef Name='MyTaxonomyField' LookupId='TRUE' /><Value Type='Lookup'>{0}</Value></Eq></Where>",
wssIds[0]);
items = list.GetItems(query);
}
return items;
}
Writing data to a TaxonomyField programmatically
Writing data to a TaxonomyField is easy once you know how to do it, but then again…isn´t everything? For this we use the method SetFieldValue contained in the TaxonomyField class. I’ve added a Button to my visual webpart and added the following code in the OnClick event:
Update 4th of November 2011: Be sure to read my follow-up post to learn how to improve this code to make it ready for a production environment!
void btnAdd_Click(object sender, EventArgs e)
{
const string TAXONOMYFIELDID = "8D0458C1-0FB7-4981-BEE1-52D0DF01895C";
SPSite site = SPContext.Current.Site;
// get the list
SPList lstTaxList = site.RootWeb.Lists.TryGetList("TaxList");
// first get the field we want to write to and cast it to a TaxonomyField
TaxonomyField taxField = lstTaxList.Fields[new Guid(TAXONOMYFIELDID)] as TaxonomyField;
if (taxField != null)
{
// Open a taxonomysession and get the associated termstore from it
TaxonomySession session = new TaxonomySession(site);
TermStore termStore = session.TermStores[0];
// get the term that we want to store in the field
Term term = termStore.GetTerm(new Guid("0cdf313f-92e2-472b-bdb9-73a25d200cf2"));
// add a new item to the list and set the values
SPListItem newItem = lstTaxList.Items.Add();
newItem["Title"] = "New Item";
taxField.SetFieldValue(newItem, term);
newItem.Update();
}
}
That’s it! If I view my list called TaxList the new item has appeared, containing the title and term set in the code:
