Tuesday, April 24, 2012

Extraction of term custom properties from list item field of managed metadata type

The task was to extract custom properties from managed metadata field of list item. Custom properties can be stored in name value like collection for each term, which is very handy in many cases.

To extract custom properties from terms, first we need to get access to appropriate term store. To achieve this I wrote simple method. All you need to do is to cast your field to TaxonomyField. Then create TaxonomySession object, access term store associated with field and get apropriate term set associated with the field.

private TermSet getTermSet(SPListItem listItem, string fieldName)
    var taxField = listItem.Fields[fieldName] as TaxonomyField;
    var session = new TaxonomySession(listItem.Web.Site);
    var termStore = session.TermStores.FirstOrDefault(ts => ts.Id == taxField.SspId);
    if (termStore != null)
        return termStore.GetTermSet(taxField.TermSetId);

    return null;

To get guids of all terms stored in our listItem object, I wrote simple helper method to extract guids. It checks if field allows to store multiple values. If so, we can cast it's value to TaxonomyFieldValueCollection type and nicely get all term ids using linq expression. If we are dealing with single value field it is eounght to cast field value to TaxonomyFieldValue and grab it's term id.
private List<Guid> getTermIds(SPListItem listItem, string fieldName)
    var taxonomyField = listItem.Fields[fieldName] as TaxonomyField;
    if (taxonomyField.AllowMultipleValues)
        var fieldValuesCollection = listItem[fieldName] as TaxonomyFieldValueCollection;
        return fieldValuesCollection.Select(x => new Guid(x.TermGuid)).ToList();
        var fieldValue = listItem[fieldName] as TaxonomyFieldValue;
        return new List() { new Guid(fieldValue.TermGuid) };

At the end, task is extremely simple. It is enough to get our term set which is connected to the field, get all guids of terms stored in list item get properties for each term.
public List<string> GetPropertyValues(SPListItem listItem, string fieldName, 
                                              List<string> customProperties)
    List<string> values = new List<string>();
    var termSet = getTermSet(listItem, fieldName);
      var termIds = getTermIds(listItem, fieldName);

      foreach (var termId in termIds)
        var term = termSet.GetTerm(termId);
        customProperties.ForEach(x => values.Add(term.CustomProperties[x]));
    return values;

With two short helper methods, it turns out to be fairly simple task to achieve.


  1. Trying to use this code however didn't understand this line of code "customProperties.ForEach(x => values.Add(term.CustomProperties[x]));"

    Where I will get the customProperties?

    Also the term returned by this line of code "var term = termSet.GetTerm(termId);" have CustomProperties with length zero.

    Any thought?

    1. Where I will get the customProperties?

      term.CustomProperties as described here is name value collection.

      Each term can have it's own collection of items accessible by it's names. List customProperties property here should contain list of names of properties for which you would like to get values (because maybe you are only interested in values for property "prop1" and "prop2".

      Also the term returned by this line of code var term = termSet.GetTerm(termId); have CustomProperties with length zero.

      I would expect that when term was created in term store it did not had assigned any custom properties. That is why in your case this collection is empty.

      You can use SetCustomProperty method to assign some custom properties to the term which later on you can retrieve from the list item when term is used there.

      What is your use case ? Maybe I will be able to help you when I you will explain to me what you are trying to achieve ?

    2. Thanks a lot for reply ! The method "getTermSet" solved my problem. :)

      My requirement was as below:
      I am browsing through the list items, if the column is Managed Meta Data I want to see all the value from associated term set.

      I followed your code blindly yesterday and messed up, so today while debuging I found the simple way to get those values using termSet.Terms collection.