Creating Site Columns Programmatically via XML

by Marcel Medina 20. July 2010 15:45

Hi folks,

From now on I will also post some quick notes of SharePoint development. I believe they are going to be very useful in our daily activities.

In this post I demonstrate how to create Site Columns programatically via XML.

Consider the following Site Columns XML:

Code Snippet
  1. <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  2.   <Field Type="Choice" Description="List of countries" Required="TRUE" Format="Dropdown" FillInChoice="FALSE" Group="World Cup 2010 Columns" ID="{05A571AD-F9D1-4aab-A703-1AF3AE393FBF}" StaticName="Country" Name="Country" DisplayName="Country" Version="1">
  3.     <CHOICES>
  4.       <CHOICE>Algeria</CHOICE>
  5.       <CHOICE>Argentina</CHOICE>
  6.       <CHOICE>Australia</CHOICE>
  7.       <CHOICE>Brazil</CHOICE>
  8.       <CHOICE>Cameroon</CHOICE>
  9.       <CHOICE>Chile</CHOICE>
  10.       <CHOICE>Côte d'Ivoire</CHOICE>
  11.       <CHOICE>Denmark</CHOICE>
  12.       <CHOICE>England</CHOICE>
  13.       <CHOICE>France</CHOICE>
  14.       <CHOICE>Germany</CHOICE>
  15.       <CHOICE>Ghana</CHOICE>
  16.       <CHOICE>Greece</CHOICE>
  17.       <CHOICE>Honduras</CHOICE>
  18.       <CHOICE>Italy</CHOICE>
  19.       <CHOICE>Japan</CHOICE>
  20.       <CHOICE>Korea DPR</CHOICE>
  21.       <CHOICE>Korea Republic</CHOICE>
  22.       <CHOICE>Mexico</CHOICE>
  23.       <CHOICE>Netherlands</CHOICE>
  24.       <CHOICE>New Zealand</CHOICE>
  25.       <CHOICE>Nigeria</CHOICE>
  26.       <CHOICE>Paraguay</CHOICE>
  27.       <CHOICE>Portugal</CHOICE>
  28.       <CHOICE>Serbia</CHOICE>
  29.       <CHOICE>Slovakia</CHOICE>
  30.       <CHOICE>Slovenia</CHOICE>
  31.       <CHOICE>South Africa</CHOICE>
  32.       <CHOICE>Spain</CHOICE>
  33.       <CHOICE>Switzerland</CHOICE>
  34.       <CHOICE>Uruguay</CHOICE>
  35.       <CHOICE>USA</CHOICE>
  36.     </CHOICES>
  37.   </Field>
  38.   <Field Type="Choice" Description="List of host cities" Required="TRUE" Format="Dropdown" FillInChoice="FALSE" Group="World Cup 2010 Columns" ID="{AF008077-3A7E-41d9-AACA-2B0997BB5E25}" StaticName="HostCity" Name="HostCity" DisplayName="City" Version="1">
  39.     <Default>Johannesburg</Default>
  40.     <CHOICES>
  41.       <CHOICE>Cape Town</CHOICE>
  42.       <CHOICE>Durban</CHOICE>
  43.       <CHOICE>Johannesburg</CHOICE>
  44.       <CHOICE>Mangaung/Bloemfontein</CHOICE>
  45.       <CHOICE>Nelson Mandela Bay/Port Elizabeth</CHOICE>
  46.       <CHOICE>Nelspruit</CHOICE>
  47.       <CHOICE>Polokwane</CHOICE>
  48.       <CHOICE>Rustenburg</CHOICE>
  49.       <CHOICE>Tshwane/Pretoria</CHOICE>
  50.     </CHOICES>
  51.   </Field>
  52.   <Field Type="Choice" Description="List of players" Required="TRUE" Format="Dropdown" FillInChoice="FALSE" Group="World Cup 2010 Columns" ID="{EA4B814A-A18B-403a-A33A-8EA5436CB540}" StaticName="Position" Name="Position" DisplayName="Position" Version="1">
  53.     <CHOICES>
  54.       <CHOICE>Defensive Midfielder</CHOICE>
  55.       <CHOICE>Forward</CHOICE>
  56.       <CHOICE>Goalkeeper</CHOICE>
  57.       <CHOICE>Left Back</CHOICE>
  58.       <CHOICE>Left Midfielder</CHOICE>
  59.       <CHOICE>Right Back</CHOICE>
  60.       <CHOICE>Right Midfielder</CHOICE>
  61.       <CHOICE>Stopper</CHOICE>
  62.       <CHOICE>Striker</CHOICE>
  63.       <CHOICE>Sweeper</CHOICE>
  64.     </CHOICES>
  65.   </Field>
  66.   <Field Type="Text" Description="The name of the player" Required="TRUE" MaxLength="255" Group="World Cup 2010 Columns" ID="{04555083-EC04-4c20-A609-42A283428374}" StaticName="PlayerName" Name="PlayerName" DisplayName="Player Name"></Field>
  67.   <Field Type="Number" Description="The age of the player" Required="FALSE" Decimals="0" Group="World Cup 2010 Columns" ID="{2F2ABEB9-ED3D-41d9-BBDE-03D1150396A1}" StaticName="PlayerAge" Name="PlayerAge" DisplayName="Player Age"></Field>
  68.   <Field Type="DateTime" Description="The date of arrival" Required="FALSE" Format="DateOnly" Group="World Cup 2010 Columns" ID="{9910FA0D-C7E8-464a-9607-CABA1502B7DC}" StaticName="Arrival" Name="Arrival" DisplayName="Arrival" />
  69. </Elements>

 

In order to add the Site Columns above, the code snippet below must be used:

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Xml;
  6. using System.IO;
  7. using Microsoft.SharePoint;
  8.  
  9. namespace SiteColumns
  10. {
  11.     public class Program
  12.     {
  13.         public static void Main(string[] args)
  14.         {
  15.             using (SPSite site = new SPSite("http://localhost/"))
  16.             {
  17.                 XmlDocument xmlDoc = new XmlDocument();
  18.  
  19.                 xmlDoc.Load(Path.GetFullPath("SiteColumns.xml"));
  20.  
  21.                 foreach (XmlElement fieldNode in xmlDoc.DocumentElement.ChildNodes)
  22.                 {
  23.                     site.RootWeb.Fields.AddFieldAsXml(fieldNode.OuterXml);
  24.                 }
  25.             }
  26.         }
  27.     }
  28. }

 

In the end the Site Columns will be created according the Figure below:


Figure 1 – Creating Site Columns

Download the solution here.

Cheers

Marcel Medina

Click here to read the same content in Portuguese.

Tags: ,

Quick Notes

Comments

12/16/2010 1:42:30 AM #

Vincent

Hi Marcel,

I am trying to write some code to update "unghosted" site columns from a Field defintion file (in a Feature), I have been trying to duplicate your approach for content types ("Load(xrdr...") but it does quite work for Fields, does it?, I wonder this technique above, if a site column already exists and in use, an exception is thrown prompting for removing "all instances", is there an easier way to update (potentially unghosted) fields from a given Xml defintion?

Thx, Vincent

Vincent United States | Reply

12/17/2010 8:50:02 PM #

Marcel Medina

Why don't you try to redeploy an updated feature? I think that approach using Reflection is not feasible.

Marcel Medina New Zealand | Reply

1/14/2011 7:29:01 PM #

Pat

Marcel, I'm scripting the creation of fields and content types to avoid using a feature in my hub.  

I'm running into an issue in that every content type I publish fails if it includes a site column created using this approach.  The columns and content types all get created fine and are usable until I try and publish.  Any ideas?  The error is:

The element 'FieldTemplate' in namespace 'urn:deployment-manifest-schema' has invalid child element 'Field' in namespace 'http://schemas.microsoft.com/sharepoint/'. List of possible elements expected: 'Field' in namespace 'urn:deployment-manifest-schema'.

Not that I think it matters, but I'm using PowerShell to do this, not a console app.

Thanks in advance

Pat United States | Reply

1/17/2011 8:19:31 AM #

Marcel Medina

Use SharePoint Manager to compare the current XML field with one that is valid. Then you can find where the problem is.

Marcel Medina New Zealand | Reply

9/16/2011 12:29:22 PM #

Bharat Pandey

Hello Brother,

You have created a file named SiteColumns.xml,Why I write this code to deploy the content types to the site. Could It not be possible to do the same using the feature.
I will deploy only this feature to a site level or web level and whenever i activate this feature the fields will be deployed on the site. same i can do with contenttype.xml?
for further accuracy, i can create a feature dependency for contenttype.xml as sitecolumn.xml should be activated before activating the contenttype.xml??

will it not be a feasible solution. rather than writing this much of code?

what are your suggestion? please provide feedback on my blog/site...

Thanks and Regards,
bharat

Bharat Pandey India | Reply

9/19/2011 1:19:13 AM #

Marcel Medina

Hi,

You can do it with features, the purpose of this post is different. It creates site columns without a feature dependency. In this approach I am using a script, not a feature.

There is no such contenttype.xml in this post, but you can create it and define a feature activation dependency, or even better, deploy the site columns and content types all together.

Cheers,

Marcel Medina New Zealand | Reply

11/9/2011 9:03:13 PM #

Timo Pitkäranta

This is probably something you might want to do when localizing CAML in sandboxed solutions

Timo Pitkäranta Finland | Reply

1/11/2012 5:56:15 AM #

Jatin

Thanks for the solution above, however there is a slight problem i'm facing. Using this i am able to add new site columns and they appear in the site settings > site columns page.

The problem is with the site columns of type 'Choice'. If i click on any column of type choice to open up its edit page, it does not show me the usual edit page for a Choice column. It takes me to a normal column edit page as if it was a 'Single line of text' field and not a choice field. I am not able to see/edit the choices in the edit page.

any hints here?

Thanks

Jatin Australia | Reply

2/27/2012 12:32:13 AM #

Marcel Medina

Hi,
Try to edit the columns at the root level of the Site Collection, then you will be able to see the choice values.

Cheers,

Marcel Medina New Zealand | Reply

1/13/2012 8:47:39 PM #

cbankx

I appreciate this article.I'm half way there

I have a question...

I created this and tossed it in a feature...

Now when I activate and deactive the feature it creates the columns if the list doesn't exist or deletes it if I deactive the feature.

The problem I have is...If we have admins that go in and create fields from the front end how would I go about looking at the list columns programatically on my feature(activation into another farm(Test/Stage/DEV/PROD) to see if something new has been added and if it's new add it to my default template so that every time the feature was Deactivated/Activated it would not lose the columns that weren't in my default XML template? I consider the default template much like the one you have above- a starting place...if you will. Since that XML document is static, how would I go about updating it with new values so that I don't erase everything that's new that is generated from the fron end.

Thanks in advance

cbankx United States | Reply

2/27/2012 12:29:27 AM #

Marcel Medina

Hi,

I understand what you want to do by updating the XML, but this is not a best practice.
A more robust solution is if you use the Content Type Hub for that, so Administrators can create/delete columns and publish them to Site Collection subscribers. The Hub automatically syncs the Content Types and Site Columns.
You can use the feature you created as a start point. Make sure you just implement the Activation method. Let the Deactivate method empty and hide the feature to avoid "accidents".

Have a look at this:
www.sharepoint4developers.net/.../...type-hub.aspx

Cheers,

Marcel Medina New Zealand | Reply

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading



Profile



Marcel Medina is a specialist in .NET/SharePoint development.

Currently working as Microsoft Consultant and Trainer in these technologies.

He has 12 years of experience in the IT area and the following certifications: MCP, MCDBA, MCAD, MCSD, MCTS (including WSS 3.0, MOSS 2007 & SharePoint 2010, Application Development), MCPD (Enterprise Application Developer & SharePoint Developer 2010) and MCT.

Support this site

If you want to keep this site running, please donate:

 

Thanks!


 

 

 


 



Site Meter