This post would sound strange and absurd but believe me this is the easiest way to provision Site Columns( Any site column including the most spoken Managed Metadata Column) and Site Content Types, You cannot go wrong with this! You would ask why you need to create it in UI since anyways you are using VS 2010. The reasoning is want SP 2010 to do all the grunt work for me and I can reuse in my VS2010 project and deploy it to the site collection. Most of folks love the UI but there are serious issues when you start building apps and writing code against content types and site columns as everything in SharePoint is GUID and XML based!!! ![]()
I would refer to a few very good articles ![]()
http://www.wictorwilen.se/Post/How-to-provision-SharePoint-2010-Managed-Metadata-columns.aspx
http://www.matdesmarais.com/2011/05/provisioning-managed-metadata-columns/
Awesome series from Andrew Connell and I follow him as anyone
Since all of them would ask you write some code in the feature receiver to bind the Column created to the id’s which in the demonstration below you will not be ! Raised Eyebrows !!! Lets dive down then ! BTW this project to deploy site columns, managed metadata columns and content types is a SANDBOX solution
!!!
- So lets start this now I had created a ContentType : NavigationContentType with two Site Columns Regions , Country
- Create Managed Metadata columns through the UI and also use a content type to add your Managed Metadata site columns
- Fire up VS 2010 and create a content type
- Now lets go to the SQL Server Management Studio on your VM and connect to the content database for the site collection where the site column was provisioned and you should see a table dbo.ContentTypes
- Okay now run a query like below:
select Definition from dbo.ContentTypes where ResourceDir='NavigationContentType'
Note in my case the Content Type I had created through UI was NavigationContentType , hence the ResourceDir with the value
- Copy the definition from the SQL Server Management Studio. In my case when I created the NavigationContentType it had two Managed Metadata Site Columns Regions , Country
<ContentType ID="0x0100167A216124CD31408B05C443BACE4F9C" Name="NavigationContentType" Group="Contoso" Version="5"> <Folder TargetName="_cts/NavigationContentType" /> <FieldRefs> <FieldRef ID="{c042a256-787d-4a6f-8a8a-cf6ab767f12d}" Name="ContentType" /> <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" Required="TRUE" ShowInNewForm="TRUE" ShowInEditForm="TRUE" /> <FieldRef ID="{34cf5520-950d-4faa-82d5-d55fdf276ad8}" Name="RegionsTaxHTField0" Hidden="TRUE" /> <FieldRef ID="{f3b0adf9-c1a2-4b02-920d-943fba4b3611}" Name="TaxCatchAll" Hidden="TRUE" /> <FieldRef ID="{8f6b6dd8-9357-4019-8172-966fcd502ed2}" Name="TaxCatchAllLabel" Hidden="TRUE" /> <FieldRef ID="{d44b3b67-91c7-45c0-8e4c-9c085ff820ab}" Name="Regions" /> <FieldRef ID="{01066e32-b406-46aa-9970-2cef4cfa25cc}" Name="CountryTaxHTField0" Hidden="TRUE" /> <FieldRef ID="{51eaecd0-d17f-45e1-a207-cb1f0076c7c1}" Name="Country" /> </FieldRefs> <XmlDocuments> <XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">PEZvcm1UZW1wbGF0ZXMgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vc2hhcmVwb2ludC92My9jb250ZW50dHlwZS9mb3JtcyI+PERpc3BsYXk+TGlzdEZvcm08L0Rpc3BsYXk+PEVkaXQ+TGlzdEZvcm08L0VkaXQ+PE5ldz5MaXN0Rm9ybTwvTmV3PjwvRm9ybVRlbXBsYXRlcz4=</XmlDocument> </XmlDocuments> </ContentType>
Now as you would see the hidden columns for Managed Metadata Site columns Regions , Country are pulled into the content type
Alright we are still not done!!!
There is a bit of clean up required
- Removing FieldRef ID for Name-“ContentType” <FieldRef ID="{c042a256-787d-4a6f-8a8a-cf6ab767f12d}" Name="ContentType" />
- Adding the Overwrite=”True” in the ContentType
- removing the XMLDocuments node as below
<?xmlversion="1.0" encoding="utf-8"?>
<Elementsxmlns="http://schemas.microsoft.com/sharepoint/">
<ContentType
ID="0x0100167A216124CD31408B05C443BACE4F9C"
Name="NavigationContentType"
Group="Contoso"
Inherits="TRUE"
Version="0"
Overwrite="TRUE"
>
<FolderTargetName="_cts/NavigationContentType" />
<FieldRefs>
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" Required="TRUE" ShowInNewForm="TRUE" ShowInEditForm="TRUE" />
<FieldRef ID="{34cf5520-950d-4faa-82d5-d55fdf276ad8}" Name="RegionsTaxHTField0" Hidden="TRUE" />
<FieldRef ID="{f3b0adf9-c1a2-4b02-920d-943fba4b3611}" Name="TaxCatchAll" Hidden="TRUE" />
<FieldRef ID="{8f6b6dd8-9357-4019-8172-966fcd502ed2}" Name="TaxCatchAllLabel" Hidden="TRUE" />
<FieldRef ID="{d44b3b67-91c7-45c0-8e4c-9c085ff820ab}" Name="Regions" />
<FieldRef ID="{01066e32-b406-46aa-9970-2cef4cfa25cc}" Name="CountryTaxHTField0" Hidden="TRUE" />
<FieldRef ID="{51eaecd0-d17f-45e1-a207-cb1f0076c7c1}" Name="Country" />
</FieldRefs>
</ContentType>
</Elements>
- Now from the same VS 2010 project, right click on the project and add “New Item” and select “List Definition from the Content Type”
- So far so good , we have a ListDefinition and the VS 2010 project should look like below .Open the schema.xml and we will dig deeper. This ListDefinition is to create site columns and would be deleted later.
- Now we just need the fields into a module for provisioning of our site columns, the special ManagedMeta Data Columns
Select the fields from the schema.xml form the ListDefinition we created and paste it into an empty module
There is clean as you would like to remove the ListID and WebID and SourceID from the fields copied from the list definition schema.xml
Note: I have removed all the Version elements from all the Field nodes
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <Field Type="TaxonomyFieldType" DisplayName="Countries" ShowField="Term$Resources:core,Language;" Required="FALSE" EnforceUniqueValues="FALSE" Group="Contoso Columns" ID="{51eaecd0-d17f-45e1-a207-cb1f0076c7c1}" StaticName="Country" Name="Country" > <Default> </Default> <Customization> <ArrayOfProperty> <Property> <Name>SspId</Name> <Value xmlns:q1="http://www.w3.org/2001/XMLSchema" p4:type="q1:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> ad6b3c2d-88ae-4112-adba-b8803d9e6aa1 </Value> </Property> <Property> <Name>GroupId</Name> </Property> <Property> <Name>TermSetId</Name> <Value xmlns:q2="http://www.w3.org/2001/XMLSchema" p4:type="q2:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> a084dd9d-3e50-4d1c-a323-8b7065617271 </Value> </Property> <Property> <Name>AnchorId</Name> <Value xmlns:q3="http://www.w3.org/2001/XMLSchema" p4:type="q3:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> 00000000-0000-0000-0000-000000000000 </Value> </Property> <Property> <Name>UserCreated</Name> <Value xmlns:q4="http://www.w3.org/2001/XMLSchema" p4:type="q4:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> false </Value> </Property> <Property> <Name>Open</Name> <Value xmlns:q5="http://www.w3.org/2001/XMLSchema" p4:type="q5:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> false </Value> </Property> <Property> <Name>TextField</Name> <Value xmlns:q6="http://www.w3.org/2001/XMLSchema" p4:type="q6:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> {01066e32-b406-46aa-9970-2cef4cfa25cc} </Value> </Property> <Property> <Name>IsPathRendered</Name> <Value xmlns:q7="http://www.w3.org/2001/XMLSchema" p4:type="q7:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> false </Value> </Property> <Property> <Name>IsKeyword</Name> <Value xmlns:q8="http://www.w3.org/2001/XMLSchema" p4:type="q8:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> false </Value> </Property> <Property> <Name>TargetTemplate</Name> </Property> <Property> <Name>CreateValuesInEditForm</Name> <Value xmlns:q9="http://www.w3.org/2001/XMLSchema" p4:type="q9:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> false </Value> </Property> <Property> <Name>FilterAssemblyStrongName</Name> <Value xmlns:q10="http://www.w3.org/2001/XMLSchema" p4:type="q10:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> Microsoft.SharePoint.Taxonomy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c </Value> </Property> <Property> <Name>FilterClassName</Name> <Value xmlns:q11="http://www.w3.org/2001/XMLSchema" p4:type="q11:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> Microsoft.SharePoint.Taxonomy.TaxonomyField </Value> </Property> <Property> <Name>FilterMethodName</Name> <Value xmlns:q12="http://www.w3.org/2001/XMLSchema" p4:type="q12:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> GetFilteringHtml </Value> </Property> <Property> <Name>FilterJavascriptProperty</Name> <Value xmlns:q13="http://www.w3.org/2001/XMLSchema" p4:type="q13:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> FilteringJavascript </Value> </Property> </ArrayOfProperty> </Customization> </Field> <Field Type="Note" DisplayName="Country_0" StaticName="CountryTaxHTField0" Name="CountryTaxHTField0" ID="{01066e32-b406-46aa-9970-2cef4cfa25cc}" ShowInViewForms="FALSE" Required="FALSE" Hidden="TRUE" CanToggleHidden="TRUE" /> <Field Type="TaxonomyFieldType" DisplayName="Regions" ShowField="Term$Resources:core,Language;" Required="FALSE" EnforceUniqueValues="FALSE" Group="Contoso Columns" ID="{d44b3b67-91c7-45c0-8e4c-9c085ff820ab}" StaticName="Regions" Name="Regions" > <Default> </Default> <Customization> <ArrayOfProperty> <Property> <Name>SspId</Name> <Value xmlns:q1="http://www.w3.org/2001/XMLSchema" p4:type="q1:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> ad6b3c2d-88ae-4112-adba-b8803d9e6aa1 </Value> </Property> <Property> <Name>GroupId</Name> </Property> <Property> <Name>TermSetId</Name> <Value xmlns:q2="http://www.w3.org/2001/XMLSchema" p4:type="q2:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> 07f6ec7e-9992-4a56-9d42-3fb98d8715b2 </Value> </Property> <Property> <Name>AnchorId</Name> <Value xmlns:q3="http://www.w3.org/2001/XMLSchema" p4:type="q3:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> 00000000-0000-0000-0000-000000000000 </Value> </Property> <Property> <Name>UserCreated</Name> <Value xmlns:q4="http://www.w3.org/2001/XMLSchema" p4:type="q4:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> false </Value> </Property> <Property> <Name>Open</Name> <Value xmlns:q5="http://www.w3.org/2001/XMLSchema" p4:type="q5:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> false </Value> </Property> <Property> <Name>TextField</Name> <Value xmlns:q6="http://www.w3.org/2001/XMLSchema" p4:type="q6:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> {34cf5520-950d-4faa-82d5-d55fdf276ad8} </Value> </Property> <Property> <Name>IsPathRendered</Name> <Value xmlns:q7="http://www.w3.org/2001/XMLSchema" p4:type="q7:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> false </Value> </Property> <Property> <Name>IsKeyword</Name> <Value xmlns:q8="http://www.w3.org/2001/XMLSchema" p4:type="q8:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> false </Value> </Property> <Property> <Name>TargetTemplate</Name> </Property> <Property> <Name>CreateValuesInEditForm</Name> <Value xmlns:q9="http://www.w3.org/2001/XMLSchema" p4:type="q9:boolean" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> false </Value> </Property> <Property> <Name>FilterAssemblyStrongName</Name> <Value xmlns:q10="http://www.w3.org/2001/XMLSchema" p4:type="q10:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> Microsoft.SharePoint.Taxonomy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c </Value> </Property> <Property> <Name>FilterClassName</Name> <Value xmlns:q11="http://www.w3.org/2001/XMLSchema" p4:type="q11:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> Microsoft.SharePoint.Taxonomy.TaxonomyField </Value> </Property> <Property> <Name>FilterMethodName</Name> <Value xmlns:q12="http://www.w3.org/2001/XMLSchema" p4:type="q12:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> GetFilteringHtml </Value> </Property> <Property> <Name>FilterJavascriptProperty</Name> <Value xmlns:q13="http://www.w3.org/2001/XMLSchema" p4:type="q13:string" xmlns="" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance"> FilteringJavascript </Value> </Property> </ArrayOfProperty> </Customization> </Field> <Field Type="Note" DisplayName="Regions_0" StaticName="RegionsTaxHTField0" Name="RegionsTaxHTField0" ID="{34cf5520-950d-4faa-82d5-d55fdf276ad8}" ShowInViewForms="FALSE" Required="FALSE" Hidden="TRUE" CanToggleHidden="TRUE" /> <Field Type="LookupMulti" DisplayName="Taxonomy Catch All Column" StaticName="TaxCatchAll" Name="TaxCatchAll" ID="{f3b0adf9-c1a2-4b02-920d-943fba4b3611}" ShowInViewForms="FALSE" Required="FALSE" Hidden="TRUE" CanToggleHidden="TRUE" ShowField="CatchAllData" Mult="TRUE" Sortable="FALSE" AllowDeletion="TRUE" Sealed="TRUE" /> <Field Type="LookupMulti" DisplayName="Taxonomy Catch All Column1" StaticName="TaxCatchAllLabel" Name="TaxCatchAllLabel" ID="{8f6b6dd8-9357-4019-8172-966fcd502ed2}" ShowInViewForms="FALSE" Required="FALSE" Hidden="TRUE" CanToggleHidden="TRUE" ShowField="CatchAllDataLabel" FieldRef="{F3B0ADF9-C1A2-4b02-920D-943FBA4B3611}" ReadOnly="TRUE" Mult="TRUE" Sortable="FALSE" AllowDeletion="TRUE" Sealed="TRUE" /> </Elements>
- The highlighted sections in the XML are very important and will tell you that we are specifying the SspID ,TermSetID and TextField ID in TaxonomyFieldType property bag in the XML itself. No code in the feature receiver etc.. in this case. really really declaratively!!!
- We are almost there , the VS 2010 project should look like
- Now I will be testing the custom content type on a different list by creating a new list
Select Allow Management of ContentTypes on the List settings and add existing content types
Made NavigationContentType as the default Content type and try adding items to the list.
Note: You have to be in the same farm to deploy this or atleast have the Managed TermStore DB migrated since the Managed Metadata columns are binding to the GUID’s in the source environment. too many options write xml with GUID’s , migrate DB etc….etc…


Great article Atul..Really helped me!
Great article, I struggled a lot of time on this issue.
However, I would moderate your last Note regarding the fact to be in the same farm for having the same GUID reference (Managed Service, Group, Term Store, etc)
I declared my TaxonomyFieldType field with just the TextField guid (referencing the hidden Note field)
TextField
{a336d7ee-486a-4e46-9886-94ee7497d3eb}
After the deployment, you just “have” to update from UI in your new environment, which is acceptable in my situation.
Cool article. But what about properties: FilterAssemblyStrongName, FilterClassName, FilterMethodName and FilterJavascriptProperty?
When I try to override them in Customization of the Field element they’re not initialized with my values – SharePoint sets the default ones… bug?
Oh, that’s sad. I won’t be able to assign this values. That what I’ve found in TaxonomyField.Update():
public override void Update()
{
base.SetCustomProperty(“SspId”, this.SspId.ToString());
base.SetCustomProperty(“AnchorId”, this.AnchorId.ToString());
base.SetCustomProperty(“UserCreated”, this.UserCreated);
base.SetCustomProperty(“Open”, this.Open);
base.SetCustomProperty(“TextField”, this.TextField.ToString(“B”));
base.SetCustomProperty(“IsPathRendered”, this.IsPathRendered);
base.SetCustomProperty(“CreateValuesInEditForm”, this.CreateValuesInEditForm);
base.SetCustomProperty(“TargetTemplate”, this.TargetTemplate);
base.SetCustomProperty(“IsKeyword”, this.IsKeyword);
if (!this.IsKeyword)
{
base.SetCustomProperty(“TermSetId”, this.TermSetId.ToString());
base.SetCustomProperty(“FilterAssemblyStrongName”, Assembly.GetExecutingAssembly().FullName);
base.SetCustomProperty(“FilterClassName”, base.GetType().ToString());
base.SetCustomProperty(“FilterMethodName”, “GetFilteringHtml”);
base.SetCustomProperty(“FilterJavascriptProperty”, “FilteringJavascript”);
}
else
{
base.SetCustomProperty(“TermSetId”, Guid.Empty.ToString());
}
base.Update();
}
Even if I assign them any call of the Update() method will override it. Damn…