There are two ways to get a collection of content types for a web site. One is the SPWeb.AvailableContentTypes collection and the other one is the SPWeb.ContentTypes collection. Right, what’s the difference then, I hear you say. A quote from the MSDN documentation:
Gets the collection of all content type templates for the current scope, including those of the current Web site, as well as of any parent sites.
Use the ContentTypes property to return only the content types of the current Web site.
The documentation is not very extensive here. The difference really is a bit vague. For you programmers out there it is good to realize that an important difference between the two exists. The AvailableContentTypes collection is read-only!
Allow me to ellaborate a bit more on that. A while ago I tried to programmatically add an information management policy to a content type (I’ll write something on that later). So, I retrieved the content type like this:
SPWeb web = SPContext.Current.Web; SPContentType contentType = web.AvailableContentTypes[new SPContentTypeId(myContentTypeId)];
When trying to add the policy to the content type, I just kept getting an error: “The collection cannot be modified”. This seemed very strange to me, and I couldn’t figure it out at first. Google and MSDN both were not very helpful in trying to find out what went wrong.
The stack trace informed me that the error occurred when the SPContentType.Update() method was called. So I started up Reflector (this really is a must-have tool for working with MOSS 2007, sad but true) to see what was happening in that method. After a while I found out that when you access the AvailableContentTypes property, a read-only collection of SPContentType objects is returned. Everything worked fine when I used the SPWeb.ContentTypes collection.
Right, that pretty much made me feel like banging my head against the wall. I spent a couple of hours trying to figure out why it wouldn’t work and it turns out to be so easy. Those are the moments when you wish that the MSDN documentation would contain more information than just a basic description of a property.
Of course, thinking about it, it probably makes sense that the AvailableContentTypes property is read-only. After all, it does return content types that belong to the parent site and you probably won’t want to go around editing those directly from a child site. Oh well, let us just be grateful that Reflector exists.
For all of those who have been living in a cave lately, here is a link to the site where Reflector can be downloaded:
Thank you, this post helped me
Oh man, this saved my day. I was getting the same freaking error and was stuck trying to find out what was going on. Thx alot!
Thanks a lot. It was a big help.
thanks a lot for your post. You saved my time.
you’re the man great post. I was struggling with very same exception… thnx a lot!
Many thanks… i was about to throw my self out the windows – you saved me
Nice catch ! Thank you !
I don’t write comments ever. But for this, I could kiss you. Thanks!
Thanks for taking the time to post this, my head couldn’t stand another wall pounding today.
You have saved my Day – THANKs!
Brilliant, I have spent too many stupid hours on this which is also true in SharePoint 2010 in case anyone is wondering.
Thanks; I was about to say you saved my day, too. Given that it’s already 3:24 in the morning, let me add an extra thank you for saving my night’s sleep .
Thanks buddy !!! You saved me.
Man you are a life saver!
Been working on policies and got stuck on the same thing. Tried, updating, didn’t work, tried deleting the policy didn’t work. Tried overriding the policy didn’t work… Just getting the same content type out of a different collection solved all my problems.