SharePoint 2010 introduces the new UpgradeActions element to the feature manifest which allows content type (CT) lifecycle management by using the new AddContentTypeField element to add new fields to existing content types.

This is great news.

Microsoft's own MSDN documentation provides this high level walkthrough of upgrading a content type: SP2010 ALM

The guidance is as quoted:

For example, perhaps you have developed a content type to which you must add a custom site column named City. You do this in the following way:

  1. Add a new element file to the feature. This element file defines the new site column and modifies the Feature.xml file to include the element file.

  2. Update the existing definition of the content type in the existing feature element file. This update will apply to all sites where the feature is newly deployed and activated.

  3. Define the required upgrade actions for the existing sites. In this case, you must ensure that the newly added element file for the additional site column is deployed and that the new site column is associated with the existing content types. To achieve these two objectives, you add the ApplyFeatureManifests and the AddContentTypeField upgrade actions to your Feature.xml file.

In following this guidance, however, I've noted that it only correctly adds the field at the root content type and does not push it down to the list level content types. The only way I can get it to push down to the list level content type is if I do not modify the original content type to include the field. But that seems counter to step 2 in the guidance and really doesn't make sense from a lifecycle management perspective as it would mean that even new installs would need upgrades to get to the current release state.

Now here is where it gets interesting. If I do the following:

  1. Add the field to the original content type .xml
  2. Add the field to the content type
  3. Add the field to a new element manifest .xml file
  4. Update the feature.xml file to include this new element manifest .xml file
  5. Increment the version on the feature
  6. Add a new VersionRange with an AddContentTypeField and PushDown="TRUE"
  7. Upgrade the feature

At this point, as mentioned, the site level content type is upgraded correctly. However, the list level instances of this content type are NOT upgraded --- or so it seems.

Now if I go to add the column manually to the list level content type -- since it is not there by default after the upgrade, the new field will show up twice!

See screencap here: http://zaanglabs.com/_tmp/2011-05-03_112047.jpg

If I loop through the list level content type fields, indeed, it has been added twice (sorry, can't post the screen cap or link).

However, at the site level, all is well and the field only occurs once. As you can see, I've been experimenting with various scenarios and changing various parameters to see if I can get this working right.

For content type ALM to make sense, we'd want to be able to have a clean deploy and upgrade deploy in the same package. But it seems that this either isn't working as intended or I have done something wrong in setting up my upgrade.

Again, if I do not add the field to the original content type manually, the upgrade occurs successfully and the new field is added to the content type at the site and list level where it's used. However, this is counter to the guidance and it seems to be an broken way of handling ALM for content types. Any insight or experience with this would be appreciated.

  • Just tried this very thing in Office 365 and its still a problem! Can't believe Microsoft haven't fixed this yet!!
    – Paul Bevis
    Commented Jun 28, 2014 at 19:57
  • @PaulBevis - I don't think they intend to fix this. Commented Jun 29, 2014 at 20:57

1 Answer 1


Point here is that when you modify a list, new content type is created, and old is set as parent for the new one.

The only way we found here is to run through the site lists and synchronize content types. It is not very hard to do, though.

foreach (var list in web.Lists)
    foreach (var listContentType in list.ContentTypes)
        // featureContentTypes - is a collection of content types,
        // which this feature provisions/updates
        foreach (var webContentType in featureContentTypes)
            syncContentTypes(webContentType, listContentType);

And the syncContentTypes method now will add new fields found in webContentType to listContentType:

void syncContentTypes(SPContentType webContentType, SPContentType listContentType)
    if (!listContentType.Id.IsChildOf(webContentType.Id))

    foreach (SPField field in webContentType.Fields)
        if (!listContentType.Fields.Contains(field.Id))
            // add new SPFieldLink here


MSDN referense: SPFieldLink

  • 2
    I took a slightly different tact: http://charliedigital.com/2011/05/03/sharepoint-content-type-lifecycle-management/ I found that if I simply removed and added the SPFieldLink on the content type at the root level and called Update(true), it would push down the changes. Of course, this is less than optimal as it would be great if PushDown="TRUE" worked as documented by Microsoft. Commented May 6, 2011 at 15:52
  • Thanks for sharing the link! It is a really useful knowledge :) Commented May 6, 2011 at 17:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.