I had a Library with various columns defined at the list level and did not use site content types. I needed to begin using site content types to better manage the data in the library. I needed a way to add the new site content types to the library and then change the existing items to the new content types without losing the metadata that was already defined on the Items.
I created the new site columns and content types and added the content types to the library. When I changed the content type of the existing items to one of the new content types, the metadata that was on the item was lost. SharePoint did not know that the field defined on the list called field1, should be moved to the new site column called as field1 in the new content type when I changed the content type of the item.
After researching a bit I realized that when I change the content type of an Item the field values are retained only if the fields are based on the same site column. The fields in my list were defined in the list itself, and were not site columns. Had the fields been site columns, and I used these site columns in my new Content types, the values would have been saved when I change content types.
With this lesson learned, I decided to create a quick WinForms app that would use the Client Object model to copy the original column to a new site column. It would:
- Create a temporary list column that was just like the original column
- Copy the value of the original list column to the temporary list column.
- Delete the original list column.
- Add a new Site Column with the same internal name and ID as the original column
- Add the new site Column to the list.
- Copy the value of the temporary list column to the new site column that was added to the list.
- Delete the temporary list column.
It’s worth noting that in my case I had some custom code already deployed that would break if the Internal Column name changed so I needed to use the temporary column to hold the values while I created the new site column with the same Internal name and ID.
The solution worked fine. I could see the site column on the gallery, and any changes I made to the Site column also updated the list column, as would be expected. (The code can be found in the project on Codeplex).
While checking to make sure that everything was OK in the Object Model after I updated one of my list columns to be a site column, I used SharePoint manager to examine the SchemaXml of the list column both before and after the column was made into a site column. To my surprise, the two were identical! It seemed nothing had changed. I then looked at the SchemaXml of the site column in the Web Fields node in SPM and saw that the SchemaXml there was the same as the SchemaXml of the list column except that it did not have two properties:
- ColName – which determines what column in the content database the column is stored
- RowOrdinal – Which I think determines where the column is displayed by default within the row.
So the net effect of all the above was that I had just added a new entry to the web.Fields collection whose SchemaXml was the same as the SchemaXml of the List Column without the ColName and RowOrdinal!
Realizing this, I created a second method in the solution (on Codeplex) that just took the SchemaXml from the list column, removed the ColName and RowOrdinal attributes, and then added it to the Web Fields collection using AddFieldAsXml.
Sure enough, the Column appeared in the Web’s Column gallery and any changes made in the gallery update the field in my list, the list column was made a site column just by adding this entry to the seb.Fields collection. It appears that the only thing that makes a column in a list a site column is that there happens to be an entry in the web’s Fields collection with the same ID.
The Project is located at http://code.msdn.microsoft.com/Convert-Sharepoint-28e28d4d
To convert a column enter your Site Url and click Get Lists.
Select the List, then select the column. Check either ‘In Place’ or ‘Copy’
Copy will use the 6 step algorith described above to create a temporary column , etc…. It displays information in the Messages box explaining what its doing. NOTE: ALL items must be checked in to use this option as it will update every item in the list! (I think you may loose your last updated info as well…)
‘In Place’ just adds an entry to the Web’s Fields collection as noted above. I runs instantly no messages are displayed.
I’ve tested it on ‘Single Line of Text’ fields and Lookup Fields and ity worked fine. Other field types may need some Tweaking.
Be sure to test Thouroghly… Use at your Own Risk 🙂
Click ‘Make Site Column’ to convert the Columns