28 February 2012

Why is my document forgetting its content type?

Background:
For our MOSS project we had a series of document libraries that used custom content types, each with its own document template. For ease of maintenance and administration, we placed all of these document templates into a common document library.

Issue:
Users would go to their document library, click the New dropdown and select the appropriate content type. This would open up the template in Word as expected. Users would then save their document and set the properties.

However, when users then navigated to the document library, they found that their document didn't retain the content type that they originally selected from the dropdown. The document had somehow 'converted' to the default content type for that library. Why?

Discussion:
The key is SharePoint's property promotion and demotion. All a document's properties including the name and ID of its content type are stored within the document as well as in the document library. You can see this by renaming a .docx file to a .zip file and examining the contents.

Whenever a document in a document library is modified, either via its contents or its document library properties, SharePoint detects this change and synchronises the properties. So, if the property value is changed in the document, SharePoint 'promotes' that change into the document library column to match, and if the document library column is changed, SharePoint 'demotes' that change into the document contents. This is most visible in the Document Information Panel or when your documents contain Quick Parts.

How is this relevant? Our template documents were all stored in a central document library, and when we created this initially we didn't allow content type management because it wasn't considered necessary. Hence the document library internally used only the SharePoint default Document content type (which has the ID 0x0101). So, the instant we placed our document templates into this library, SharePoint converted the documents from our custom content types into Document. It also updated the internal contents of these document templates - via property demotion - to reflect that fact.

When users created new documents from these templates and saved them into a document library, the internal information stored within the template was retained, and SharePoint recognised that the documents were actually of the Document content type. It then promoted that information into the document properties at the document library level, overriding the selection made by the user from the New dropdown! Because of the way our custom content types and libraries operated, our document libraries didn't have the Document content type enabled. SharePoint couldn't match the content types accurately and (fairly sensibly) just went with the default content type for the library.

Solution:
We needed a way to make sure that the content type information was always preserved for our custom content types, so we enabled content type management for the document library containing the templates. We then ensured that each template was an instance of the content type for which it was the template. Then, there was no conflicting content type information to confuse SharePoint and the entire process worked perfectly.

Summary:
The key is that if you're going to store content type templates in SharePoint, make them instances of their respective content type. This is easy enough but it has a few implications:
  • It will be difficult to reliably reuse a template across multiple content types
  • If you're reusing content types across multiple site collections, make sure your content type IDs match - the SP2010 content type hub is useful in this case
SharePoint's property promotion is a pretty amazing thing, but it can edit your documents in ways you're not expecting - I've even seen it conflict with custom event receivers! When troubleshooting unexpected document metadata issues, remember that the process is always there, synchronising silently in the shadows...