In this post I want to cover how to create managed metadata columns. The other posts in this series are as follows (I'll update this list as they are published):
- SharePoint 2010 Managed Metadata - About the series...
- SharePoint 2010 Managed Metadata - What is it?
- SharePoint 2010 Managed Metadata - Why I love it!
- SharePoint 2010 Managed Metadata - Global vs. Local Term Sets
- SharePoint 2010 Managed Metadata - Moving/Copying MMS Instances / Term Stores between Environments
- SharePoint 2010 Managed Metadata - In Depth Look into the Taxonomy Parts
- SharePoint 2010 Managed Metadata - Creating Managed Metadata Columns
Creating columns on a SharePoint list is fairly straightforward for most folks as the browser is such an easy option. Another creation option is SharePoint Designer 2010. However in both of these scenarios the creation of the columns is not very portable. These columns are only going to live within the confines of the list you created them within. Be forewarned!
What about the situations where you want to have a more repeatable scenario in creating the columns of type Managed Metadata? In these cases you want to get everything boxed up in a package (*.wsp). The only way to do this is to either create the column declaratively or programmatically. However there can be issues with this approach.
First, look at your two options. You can create site / list columns in a repeatable fashion using the object model typically either in a Feature receiver or maybe as a PowerShell Script. The other option is to create the column using the Feature schema (XML). Both options have their advantages and disadvantages. I've had some great conversations watching folks go back and forth on the merits of a declarative vs. programmatic approach.
Wictor Wilen (here & here) and Ari Bakker (here & here) have written a good bit about this subject. Now I'd like to give you my opinion. Generally speaking I prefer to create columns declaratively. However I found quickly that you couldn't do a 100% pure declarative approach when creating Managed Metadata columns. You always had some extra work to do to clean up links to the term store and term set the column was attached to. Sure, in many instances you could define these values in XML, but it always felt like an exercise that was "do it only in XML for the sake of doing it" not because that is what made sense. Most of the time I found I needed to add some logic around getting the term store or term set and not just specifying some ID. This is demonstrated in both Wictor's and Ari's posts... they both show how to create the columns declaratively and then have some code do the extra work.
However I'd like to offer another approach. Instead of doing it declaratively, why not do the whole column programmatically? When you create the column programmatically you don't have any extra work to do like creating the note field or the other hidden fields. When you create the Managed Metadata column programmatically, SharePoint handles all the other creation of the hidden fields and wiring up tasks. There's no extra work that you have to do as is shown in both Wictor's and Ari's posts.
For instance, consider this code creating a new column on a list:
Now using the Server Explorer tool window in Visual Studio 2010 notice the other hidden columns were created for us. Here are the two event receivers automatically added to a list:
And here are all the fields (#1 is what I created in code, #2 & #3 are the new hidden fields):
If you need some more info on these hidden fields, check out my other post on the subject.
Perfect... exactly what we wanted! Now I too wish there was a declarative only way to do this but fact is there just isn't. So for now, this method works just fine for me and doesn't require any extra work to do what SharePoint should already be doing for us.