* Update 15 May 2010 – this isn’t a problem! After some feedback from Chak’s and some retesting I’m happy to say that CAML features and the content type publishing hub work together fine. I can’t reproduce the problem and neither can Paul so I’m going to park this as a SharePoint X-File. I’d recommend you don’t use the method below unless you have a good reason to mix OM/CAML features in your deployment.
Paul Grimley wrote a post a while ago which highlighted a problem * with the content type publishing capability of SharePoint 2010. The particular problem highlighted by Paul’s post is the inability for content types to be published by the content type hub if they have been deployed by declarative CAML in a feature…seriously!
So we have two components of SharePoint 2010 – feature based content types and the content type hub – which are incompatible with each other. In my opinion there are lots of reasons you may want to deploy content types via features including:
- Portability – deploying artefacts such as content types between environments such as DEVELOPMENT, UAT and PRODUCTION is much easier when they are wrapped up in a feature
- Visual Studio 2010 support – you can leverage the content type SPI’s (SharePoint Project Item) for creating content types in your solution which provides a nice interface for selecting its parent etc etc
- Readability – CAML based features are (sort of) human readable which sometimes makes it a lot easier to determine what is happening within the feature by reading the XML than the source code
- Best Practice – haven’t we been told time and time again that it’s a best practice to deploy customisations to SharePoint via features and solutions?
So there are lots of reasons why we want to use features but we also want to use the content type hub, what are our options? After a bit of trial and error I came up with the following pattern that seems to work well albeit with a few limitations.
The Workaround
The API for 2010 provides a new constructor for the SPContentType class that lets us create a content type via the object model with a specified ID. This is a important change from the 2007 API which will be the basis of the workaround:
- Create a base content type using the Object Model:
string baseContentTypeId = "0x010100ee23a9df11631348b5a5ac7fdfd66b49"; SPContentTypeId contentTypeId = new SPContentTypeId(baseContentTypeId); SPContentType baseContentType = null; baseContentType = contentTypes[contentTypeId]; if (baseContentType == null) { baseContentType = new SPContentType(contentTypeId, contentTypes, "Base Content Type Publishing"); contentTypes.Add(baseContentType); }
- Any content types that should be publishable via the content type hub must be a descendant of this base content type (either a child, grand child etc)
<!-- Parent ContentType: Base Content Type Publishing (0x010100EE23A9DF11631348B5A5AC7FDFD66B49) --> <contenttype id="0x010100EE23A9DF11631348B5A5AC7FDFD66B4900e54d81511bac4ad0837dd2ca3fb228e7" version="0" inherits="TRUE" description="A feature based Content Type that is publishable via the Content Type Hub" group="Custom Content Types" name="Base Document Content Type" />
My preference is to create the base content type via a ‘pre-requisite’ feature and then create a separate feature with the CAML based content types which will be dependent on this base content type feature. So far I’ve tested this ‘pattern’ with the following results:
- These CAML based content types are disconnected from the features XML upon creation. This means any updates to the feature will not affect the content types. Updates to the published content types can be made by forcefully deactivating/reactivating the features but this is a risky operation as you might not know what has happened to the content types once they have been published.
- If the attribute Overwrite=”TRUE” is included in either the content type or a field used by the content type the content type it won’t be published. It doesnt matter if the content type is a descendant of your base (publishable) content type or not it will never be published if you use the overwrite attribute.
- These content types can be updated via the feature upgrade framework.
Unfortunately there are more than just a few things in SharePoint that you expect to work a certain way, or just work, that don’t. I love the platform but occasionally these “it almost works” moments can be pretty frustrating! If you have any feedback on this workaround I’d be keen to hear from you.
I did a joint presentation with Alex Dean at the Christchurch SharePoint User Group which was a brief overview of SharePoint Development 2010 with Visual Studio 2010 and a discussion of some (not all) of the challenges. Alex kicked it off and did a great introduction and then I talked about a few of the problems I have experienced and how they can be worked around.
A big thanks to Alex for coming down from Wellington and doing two presentations. Great effort!
The slides (and of more use the links inside them) are on SlideShare and embedded below:
This is a common error if you try to delete a content type in SharePoint. SharePoint is quite rightly trying to stop you from breaking anything by removing a content type if:
- the content type is being used by a list or library somewhere in your site; or
- another content type inherits from the content type you are trying to delete
SharePoint provides the SPContentTypeUsages class which allows you to track where the content type is being used and there are some good posts about other things to look for when tracking down the offending content type. In SharePoint 2010 there is an extra place you need to look…the recycle bin.
It seems SharePoint 2010 throws this error if you have assigned the content type to a list or library and it has been deleted to the recycle bin. I’m not sure why, and in this circumstance SPContentTypeUsages is no good to you – it won’t have any references about lists in the recycle bin.
Just remember next time you get this error to check the recycle bin and delete any lists or libraries that reference the content type.
Side Note – SharePoint Manager
A really easy way to get access to the information provided by SPContentTypeUsages is via SharePoint Manager.
This is what you will see if a list referencing the content type is in the recycle bin…nothing!