Using taxonomy fields in SharePoint 2010: Part II

By bhoeijmakers at November 21, 2010 02:13
Filed Under: .NET, SharePoint 2010

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:

 

TaxListSettings

 

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):

 

TaxListView

 

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:

 

TaxListNewItem

Comments (3) -

12/21/2010 4:08:24 AM #

Superb post! Thanks for your valueable inputs, your post was very much helpful Smile

Cheers
DB

DB United States | Reply

5/11/2011 7:31:13 AM #

Nice post and very helpful. Thanks heaps!!

W0ut Belgium | Reply

7/27/2011 8:53:22 AM #

Nice Article, I was waiting for such one since long.

saurin India | Reply

Pingbacks and trackbacks (1)+

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading


About the author

Bart-Jan Hoeijmakers is Lead SharePoint Developer at VX Company. Since 2006 he is the driving force behind the development of several enterprise SharePoint projects within VX Company. He is a hardcore developer in both SharePoint and ASP.NET and loves to dive into the dark sides of SharePoint development.

Month List