Please read this document first.
You can see, that there are two ways to determine parent-child relationship between content types. You can of course use always the ParentCT+00+GUID way, like I did, but then you will surely bang your head against a wall when it comes to work with publishing.
I created a content type schema for a publishing site, where A was parent for AB, which was parent for ABC, etc. For every content type, I used the ParentCT+00+GUID inheritance schema, which gave me a pretty long content type id for ABC, but what the heck, Sharepoint will handle it, won’t it?
Then I created Page Layouts and associated them with the appropriate content type. I deployed it, I created page instances from the different page layouts. Everything worked just fine. Me happy 🙂
Then I noticed that even I had one page instance from each page layout (A, AB and ABC), the content type of all three page instances was ABC. I wasn’t so happy anymore, because I built a user control which was using filtering based on the content type of the page instance, so I needed this working correctly.
I did another experiment, and I noticed, that if I add the content type manually to the document library (Settings->Add existing content type from site) then it works correctly: page instance of A will have content type A, page instance of AB will have content type AB and so on.
So I had no other choice, but debug Sharepoint. With the help of the 30 days trial version of Reflector VS PRO, I found the exact flow which takes place when you create a document based on a page layout. At on moment it searches for the BestMatch of a content type id in a content types collection. That code looks like this:
public static SPContentTypeId BestMatch(SPContentTypeId contentTypeId, IEnumerable contentTypeIdCollection)
SPContentTypeId result = SPContentTypeId.Root;
int num = 0;
foreach (SPContentTypeId sPContentTypeId in contentTypeIdCollection)
int num2 = sPContentTypeId.CountCommonBytes(contentTypeId);
if (num2 > num)
result = sPContentTypeId;
num = num2;
if (num2 == num && sPContentTypeId.Length < result.Length)
result = sPContentTypeId;
I can’t say I understood what’s happening there, so I tried a different approach. 🙂
There was another publishing project, created by another team, which was working just fine, though it was also using content type inheritance. I took a look at the content type definitions from that project and it struck me immediately: these content type ids are much SHORTER!
Pay attention to that link I mentioned above. Create a content type id using the ParentCT+00+GUID only when the parent is a “foreign” content type, meaning it’s either Sharepoint’s or a third party. After you created the first leaf of your content type inheritance tree that way, you can (and should!) continue using the other option: ParentCT+[01..FF] I have rewritten all my content type ids this way, and BANG: the page instance was created with the correct content type!