Skip to main content

Cloud

Defining and deploying managed metadata fields in code

We, as a company, have been in the process of moving all of our internal systems to SharePoint 2010 and one particular feature we wanted to take advantage of is Managed Metadata. I was tasked with creating all of the content types and list definitions we would use across our extranet. The first thing I had to do was pick out which existing columns we could convert to managed metadata columns, hopefully giving us a better user experience and a better ability to search our existing content.
I came up with a few criteria for looking at our current site columns and deciding if they would fit as managed metadata columns based on our goal of a better user experience and more available and relevant search results:

  1. The column must have multiple valid values
  2. Values for the column must be at least partly defined
  3. There is a good chance that the values for this column will be expanded upon in the future
  4. Users may want to define more than one pre-defined value in the same column

This list may not be complete, but it gave me a good place to start from.
Before creating any of my fields, content types, or lists I made a feature that would deploy all of the terms I had defined for these columns. I separated the values out into separate term sets for each column and placed all of these term sets in a term group that is housing all of the term sets we are using on our extranet. Bob Moore has a great blog post describing how to do this already so I won’t repost what he has written.
I created a new empty element to house my fields and then went to work defining the generic fields from across the site. Then i defined all of my managed metadata fields. To not bore you with a ton of code I will follow the “Bug Type” field I created from start to finish. Here is the XML that defines the field:

<Field ID="{64115AE4-61C6-4AF5-B96B-5A6712880BE4}"
         Name="BugType"
         ShowField="Term1033"
         StaticName="BugType"
         Group="Extranet_SiteColumns"
         Type="TaxonomyFieldType"
         DisplayName="Type"
         EnforceUniqueValues="FALSE"
         Required="TRUE"/>

.ExternalClassB41FEC5C48F44F9A932A3E0ABE1D8213 .csharpcode, .ExternalClassB41FEC5C48F44F9A932A3E0ABE1D8213 .csharpcode pre
{font-size:small;color:black;font-family:consolas, “Courier New”, courier, monospace;background-color:#ffffff;}
.ExternalClassB41FEC5C48F44F9A932A3E0ABE1D8213 .csharpcode pre
{margin:0em;}
.ExternalClassB41FEC5C48F44F9A932A3E0ABE1D8213 .csharpcode .rem
{color:#008000;}
.ExternalClassB41FEC5C48F44F9A932A3E0ABE1D8213 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassB41FEC5C48F44F9A932A3E0ABE1D8213 .csharpcode .str
{color:#006080;}
.ExternalClassB41FEC5C48F44F9A932A3E0ABE1D8213 .csharpcode .op
{color:#0000c0;}
.ExternalClassB41FEC5C48F44F9A932A3E0ABE1D8213 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassB41FEC5C48F44F9A932A3E0ABE1D8213 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassB41FEC5C48F44F9A932A3E0ABE1D8213 .csharpcode .html
{color:#800000;}
.ExternalClassB41FEC5C48F44F9A932A3E0ABE1D8213 .csharpcode .attr
{color:#ff0000;}
.ExternalClassB41FEC5C48F44F9A932A3E0ABE1D8213 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassB41FEC5C48F44F9A932A3E0ABE1D8213 .csharpcode .lnum
{color:#606060;}
One thing that is really important to remember is to always have the ‘EnforceUniqueValues’ property set to false. I learned the hard way that this property makes the field a key for the item, so all values would have to be unique between all items in a list. Another important property is the ‘ShowField’ property, I have only seen it set to ‘Term1033’, so this is how I set it for all of my managed metadata fields.
After creating the field I added an event receiver this feature that hooks up all of my managed metadata fields to the term sets I created for them. I pulled out the code for all of my other managed metadata columns, but you should get the gist.

 public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            string termGroupName = "ExtranetTermSets";
            string BUG_TYPE = "BugType";
           //Dictionary of fields and their guids
            Dictionary<string, string> termSetFieldGuid = new Dictionary<string, string>();
            termSetFieldGuid.Add(BUG_TYPE, "64115AE4-61C6-4AF5-B96B-5A6712880BE4");
            SPSite site = SPContext.Current.Site;
           //hook up all managed metadata columns to terms
           TaxonomySession session = new TaxonomySession(site);
           //TermStores[0] is the default, you can also pass a string of the name of the term store you want to use
           TermStore termstore = session.TermStores[0];
           Group group = termstore.Groups[termGroupName];
           foreach (KeyValuePair<string, string> fieldSet in termSetFieldGuid)
           {
               TermSet pbxTermSet = group.TermSets[fieldSet.Key];
               TaxonomyField mmField = (TaxonomyField)site.OpenWeb().Fields[new Guid(fieldSet.Value)];
               mmField.SspId = termstore.Id;
               mmField.TermSetId = pbxTermSet.Id;
               mmField.IsPathRendered = false;
               mmField.Update();
           }
        }

And there you have it. I also created content types with these fields and custom lists using those content types. Adding these managed metadata columns to a content type is exactly the same as any other column.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Brian Hulse

More from this Author

Follow Us