Enterprise software development and consulting for various organizations, industries and domains.

Saturday, August 21, 2010

How to set managed metadata field value through code

Recently one of our clients reported an issue that setting taxonomy field value through code doesn't update the field value.

We noticed interesting fact, that even though value is stored in a field, UI control still shows an old value. After spending some time in a reflector digging in Microsoft.SharePoint.Taxonomy.dll we found out a way how SharePoint stores managed metadata and enterprise keywords values.

Guys from Microsoft use pretty simple approach, they store technical information in a hidden field created with the following algorithm.

string str;
string str2;
int num = 0;
while (fields.ContainsField(base.Title + "_" + num.ToString(CultureInfo.InvariantCulture)))
{
    num++;
}
if (this.IsKeyword)
{
    str = "TaxKeywordTaxHTField";
    str2 = "TaxKeywordTaxHTField";
}
else
{
    str = base.Title + "_" + num.ToString(CultureInfo.InvariantCulture);
    str2 = base.InternalName + "TaxHTField" + num.ToString(CultureInfo.InvariantCulture);
}

Where str and str2 are DisplayName and InternalName of a hidden field respectively.

So, in order to set taxonomy field value, either Managed Meatadata or Enterprise Keywords field, we used this piece of code:

var currentItem = SPContext.Current.Item;

// set field value
item[fieldName] = currentItem[fieldName];

// find hidden field and set it's value
SPField htField = GetHTField(item, fieldName);
item[htField.StaticName] = currentItem[htField.StaticName];

GetHTField method is shown below:

private SPField GetHTField(SPItem item, string fieldName)
{
    foreach (SPField field in item.Fields)
    {
        if (field.StaticName.StartsWith(fieldName) && field.StaticName.Contains("TaxHTField"))
        {
            return field;
        }
    }
    return null;
}

This code was used in a code behind of a layout page with FormComponent control thus we were able to get current item from SPContext.

In the next post, for those who are not able to use values from SPContext's current item, I will tell about format of a taxonomy hidden field value and show how to calculate it manually.

3 comments:

  1. 1) There are cases (though they are ill-defined) when the associated field can have a different internal name. You can see my related post in the MSDN forums: http://social.technet.microsoft.com/Forums/en-US/sharepoint2010programming/thread/f0b66ae0-234b-4fd9-9eea-8fc7fd497876/

    2) Is there any possible case in which num.ToString(CultureInfo.InvariantCulture) could be anything other than "0"? I wouldn't think there is, but my knowledge of globalization is not great.

    ReplyDelete
  2. After some intense investigation, I've found the above article is no longer valid for SharePoint installations featuring the December 2010 Cumulative Update. I'm not sure exactly which patch caused changes but the underlying mechanisms for how SharePoint creates and handles these supporting columns has undeniably changed.

    ReplyDelete
  3. Yes, good catch. I would suggest to use TaxonomyFieldValue class.

    ReplyDelete