Nick Hadlee's Blog on SharePoint and Other Occasional Rants…


Making Features that Deploy Content Types Compatible with the Content Type Hub
January 8, 2011, 10:55 am
Filed under: 2010, Content Types, Development, Tips & Tricks

* 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.