Get Taxonomy Field Values with CSOM Programmatically

To read taxonomy field value(s) from a list item via CSOM can be quite cumbersome. Chris Domino explained those problems very detailed in his blog post.

I had the same problem that the CSOM API did not create the expected objects by itself but just returning a key value dictionary containing the taxonomy values. So I decided to write two extension methods for the ListItem class.

private const string ChildItems = "_Child_Items_";
private const string ObjectType = "_ObjectType_";

public static TaxonomyFieldValue GetTaxonomyFieldValue(this ListItem item, string internalFieldName)
{
    if (item == null) throw new ArgumentNullException("item");
    if (internalFieldName == null) throw new ArgumentNullException("internalFieldName");

    if (!item.FieldValues.ContainsKey(internalFieldName))
    {
        throw new ArgumentException(string.Format("The field '{0}' does not exist.", internalFieldName), "internalFieldName");
    }

    var value = item[internalFieldName];
    var taxonomyFieldValue = value as TaxonomyFieldValue;
    if (taxonomyFieldValue != null)
    {
        return taxonomyFieldValue;
    }

    var dictionary = value as Dictionary<string, object>;
    if (dictionary != null)
    {
        return ConvertDictionaryToTaxonomyFieldValue(dictionary);
    }

    throw new InvalidOperationException(
        string.Format(
            "Could not convert value of field '{0}' to a taxonomy vield value. Value is neither a TaxonomyFieldValue nor a Dictionary",
            internalFieldName));
}

public static ReadOnlyCollection<TaxonomyFieldValue> GetTaxonomyFieldValueCollection(this ListItem item, string internalFieldName)
{
    if (item == null) throw new ArgumentNullException("item");
    if (internalFieldName == null) throw new ArgumentNullException("internalFieldName");

    if (!item.FieldValues.ContainsKey(internalFieldName))
    {
        throw new ArgumentException(string.Format("The field '{0}' does not exist.", internalFieldName), "internalFieldName");
    }

    var value = item[internalFieldName];
    var taxonomyFieldValueCollection = value as TaxonomyFieldValueCollection;
    if (taxonomyFieldValueCollection != null)
    {
        return new ReadOnlyCollection<TaxonomyFieldValue>(taxonomyFieldValueCollection.ToList());
    }

    var dictionary = value as Dictionary<string, object>;
    if (dictionary != null)
    {
        return new ReadOnlyCollection<TaxonomyFieldValue>(ConvertDictionaryToTaxonomyFieldValueCollection(dictionary));
    }

    throw new InvalidOperationException(string.Format(
        "Could not convert value of field '{0}' to a taxonomy vield value. Value is neither a TaxonomyFieldValue nor a Dictionary",
        internalFieldName));
}

private static TaxonomyFieldValue ConvertDictionaryToTaxonomyFieldValue(Dictionary<string, object> dictionary)
{
    if (!dictionary.ContainsKey(ObjectType) || !dictionary[ObjectType].Equals("SP.Taxonomy.TaxonomyFieldValue"))
    {
        throw new InvalidOperationException("Dictionary value represents no TaxonomyFieldValue.");
    }

    return new TaxonomyFieldValue
    {
        Label = dictionary["Label"].ToString(),
        TermGuid = dictionary["TermGuid"].ToString(),
        WssId = int.Parse(dictionary["WssId"].ToString(), CultureInfo.InvariantCulture)
    };
}

private static List<TaxonomyFieldValue> ConvertDictionaryToTaxonomyFieldValueCollection(Dictionary<string, object> dictionary)
{
    if (!dictionary.ContainsKey(ObjectType) || !dictionary[ObjectType].Equals("SP.Taxonomy.TaxonomyFieldValueCollection"))
    {
        throw new InvalidOperationException("Dictionary value represents no TaxonomyFieldValueCollection.");
    }

    if (!dictionary.ContainsKey(ChildItems))
    {
        throw new InvalidOperationException(string.Format("Missing '{0}' key in TaxonomyFieldValueCollection field.", ChildItems));
    }

    var list = new List<TaxonomyFieldValue>();
    foreach (var value in (object[])dictionary[ChildItems])
    {
        var childDictionary = (Dictionary<string, object>) value;
        list.Add(ConvertDictionaryToTaxonomyFieldValue(childDictionary));
    }

    return list;
}

Leave a Reply

Your email address will not be published. Required fields are marked *

4 × four =