Thursday, October 10, 2013

Solved: “The collection cannot be modified” error on Content Type Update.

I recently came across a problem whereby an exception is thrown when Update() is called on a SharePoint 2010 content type.

Let me explain the scenario… there are two ways to retrieve content types, those are:

1- SPWeb.ContentTypes which gets the collection of content types for the website.
When you are referring to an SPWeb object and need to go through the content types for that web, the SPWeb.ContentTypes property will only show you a list of content types that have been defined at that site level, not a full list of Content Types that the web has available to it.

and

2- SPWeb.AvailableContentTypes which gets the collection of all content type templates that apply to the current scope, including those of the current website, as well as any parent websites. Use the AvailableContentTypes property if you want to get the list of all content types that are available to the web (including all of those defined at sites above it in the site structure, all the way to the top of the site collection).

Because I wanted my code to retrieve the content type regardless where the content type was available (current web or root web / site collection level) I used SPWeb.AvailableContentTypes.

To illustrate this I created the following very simple C# console app which uses the SharePoint object model to move a custom content type from one group to another.

So the following code should return the content type and allow me to update it... but it won’t work...

using (SPSite site = new SPSite(demositeURL))
{
    try
    {
        SPContentType contenttype = site.RootWeb.AvailableContentTypes["Demo Content"];
        if (contenttype != null)
        {
            contenttype.Group = "Demo Content Types";
            contenttype.Update();
        }
    }
    catch (Exception e)
    {
        System.Diagnostics.Debug.WriteLine(e.Message);
    }
}

If I run the code, SharePoint throws a “The collection cannot be modified.” Exception on contenttype.Update();

image

Thanks to Bernado Nguyen-Hoan I found that you have to ensure that the content type you are updating was not retrieved from the SPWeb.AvailableContentTypes collection. Content types retrieved from this collection (as oppose to SPWeb.ContentTypes) are read-only.
SPWeb.AvailableContentTypes has a non-public property called ReadOnly and its value is true. Therefore content types retrieved from this collection also have a non-public property Collection.ReadOnly – which is also true.

So if you need to update a content type, rather retrieve it from the SPWeb.ContentTypes instead of retrieving it from SPWeb.AvailableContentTypes.

If you modify the code example from above and change this line:

SPContentType contenttype = site.RootWeb.AvailableContentTypes["Demo Content"];
to:
SPContentType contenttype = site.RootWeb.ContentTypes["Demo Content"];

The code will execute successfully.

using (SPSite site = new SPSite(demositeURL))
{
    try
    {
        SPContentType contenttype = site.RootWeb.ContentTypes["Demo Content"];
        if (contenttype != null)
        {
            contenttype.Group = "Demo Content Types";
            contenttype.Update();
        }
    }
    catch (Exception e)
    {
        System.Diagnostics.Debug.WriteLine(e.Message);
    }
}

Enjoy!!!!

0 comments:

Post a Comment