Question

I am having a problem with a custom site column in SP2007, whose field type recently changed. I have defined features for the following artifacts, which are deployed at the site collection scope:

  1. A feature containing several custom site columns
  2. A feature containing a custom content type that references the custom site columns using the element
  3. A feature containing a custom list template (based on the built-in Custom List template) which references the custom site columns, and applies the custom content type.

We recently changed the schema of one of the custom site columns. Specifically, we changed the "Type" attribute from "Text" to "Note". Here is the original schema:

<Field ID="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" SourceID="http://schemas.microsoft.com/sharepoint/v3" Name="CurrentStatus"
StaticName="CurrentStatus" Group="My Site Columns" ColName="CurrentStatus" Type="Text" ShowInEditForm="FALSE" ShowInNewForm="FALSE" ShowInFileDlg="FALSE" DisplayName="Current Status" Description="The current status."> </Field>

And here is the updated schema with the new 'Note' type:

<Field ID="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" SourceID="http://schemas.microsoft.com/sharepoint/v3" Name="CurrentStatus" StaticName="CurrentStatus" Group="My Site Columns" ColName="CurrentStatus" Type="Note" RichText="TRUE" IsolateStyles="TRUE" RichTextMode="FullHtml" ShowInEditForm="FALSE" ShowInNewForm="FALSE" ShowInFileDlg="FALSE" DisplayName="Current Status" Description="The current status."> </Field>

Now, I recognize that this is not a supported change and I plan to avoid it at all costs in the future. But in our initial testing, we found that all of our existing lists (created using the old site column schema) were seemlessly upgraded to the new schema after deploying the new features. However, occasionally on some systems we are finding that the following error occurs whenever someone tries to create a new instance of a list from our template:

Non-supported field type change.

The field cannot be changed to the new type. Please check the new type and try again. at Microsoft.SharePoint.Library.SPRequestInternalClass.UpdateField(String bstrUrl, String bstrListName, String bstrXML) at Microsoft.SharePoint.Library.SPRequest.UpdateField(String bstrUrl, String bstrListName, String bstrXML)

Is there anything we can do to fix the problem (other than reverting the field schema), or are we stuck?

Was it helpful?

Solution

Interesting - I used this very scenario (upgrading a field from text to note) in a demo recently in a conference talk, to show off SharePoint 2010's new upgradable Features framework. In both SP2007 and SP2010, changing the type of fields which are in use is unsuppported, as you've discovered.

My recommendation would be:

  1. Take a backup in case rolling back somehow makes the issue works.
  2. Revert the field schema back to 'text'.
  3. Use a different approach to change the field type, namely:
  4. Provision the new note field
  5. Write code to iterate all lists and copy data from old field into new
  6. Mark old field as hidden

Obviously you'll have a few things to think about if you have many sites/webs/lists/list items, but you'd have the scale challenge even if you hadn't gone down the original route.

In case it's useful, here's the code I used (in my case, in a SP2010 FeatureUpgrading event, but you could just as appropriately use it in a FeatureActivating event or similar). Note that this was in a web Feature which was upgraded (i.e. activated for SP2007) on all webs containing the list:

List<SPField> fieldsToUpgrade = new List<SPField>();

// find all the lists in this web using the 'Tourist Activity' content type..
SPListCollection genericLists = parentWeb.GetListsOfType(SPBaseType.GenericList);
foreach (SPList list in genericLists)
{
    if (list.ContentTypes[contentTypeName] != null)
    {
        // copy list data to new field..
        foreach (SPListItem item in list.Items)
        {
            item[newFieldName] = item[oldFieldName];
            item.SystemUpdate();
        }

        // mark old field as hidden..
        SPField oldField = list.Fields.GetField(oldFieldName);
        fieldsToUpgrade.Add(oldField);
    }
}

foreach (SPField field in fieldsToUpgrade)
{
    field.Hidden = true;
    field.Update();
}

OTHER TIPS

you can Do it in my way.

private static void ChangeFieldType() {
            SPSecurity.RunWithElevatedPrivileges(delegate() {
                using (SPSite site = new SPSite("YourSiteUrl")) {
                    using (SPWeb web = site.OpenWeb("YourWebUrl") {
                        try {
                            web.AllowUnsafeUpdates = true;
                            SPList list = web.Lists["YourListName"];
                            SPField changeTypeField = list.Fields["YourField"];
                            string schema;
                            schema = changeTypeField.SchemaXml;
                            schema = schema.Replace("Type=\"Text\"", "Type=\"Note\"");
                            changeTypeField.SchemaXml = schema;
                            changeTypeField.Update();
                            web.AllowUnsafeUpdates = false;
                        } catch (Exception e) {
                            Console.WriteLine(e.Message);
                        }
                    }
                }
            });
        }
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top