By: Arjun Chakraborty
Today, I would like to note that although site content types from parent webs appear on the content type gallery in a child site, this is not necessarily true within the SharePoint API. When iterating through the child SPWeb’s SPContentType list, you will not find any of the content types created in a parent site. To demonstrate this, I will show you a simple site collection, where there is one root site, with a custom site content type, and a subsite, with a list that uses the custom site content type, as a list content type. I will also use a workflow in the subsite’s list, to demonstrate what I mean.
Setup:
Here is the Root site, with its custom content type, based on the ‘Item’ content type:

Here is the subsite, with the demonstration list:

Inside the list, we see one item, coincidentally of the same content type as the one in the root site:

We will be running a workflow on this item, which will provide some output in the Notes column.
Finally, let’s note that in the browser, we can actually see the custom content type in the sub site’s content type gallery, but the content type is stated to be part of the root site (“Test Site”):

Plan of Action:
I will run the following, simple workflow code block. It will show us the sizes of the Content Type lists of the List, the Sub-Site and the Root-Site. It will also show us which of these lists contain a content type called “CustomItem”.
//start of method
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
string contentTypeName = workflowProperties.Item.Title;
StringBuilder message = new StringBuilder();
SPContentTypeCollection rootWebContentTypes =
workflowProperties.Site.RootWeb.ContentTypes;
SPContentTypeCollection thisWebContentTypes =
workflowProperties.Web.ContentTypes;
SPContentTypeCollection thisListContentTypes =
workflowProperties.List.ContentTypes;
CheckForContentType("Root Web", contentTypeName, message, rootWebContentTypes);
CheckForContentType("This Web", contentTypeName, message, thisWebContentTypes);
CheckForContentType("This List", contentTypeName, message, thisListContentTypes);
SPListItem item = workflowProperties.Item;
item["Notes"] = message;
item.SystemUpdate(false);
}//end of method
//start of method
private static void CheckForContentType(string location, string contentTypeName,
StringBuilder message, SPContentTypeCollection contentTypeList)
{
message.AppendLine(location + ":");
message.AppendLine("Count = " + contentTypeList.Count);
foreach (SPContentType ct in contentTypeList)
{
if (ct.Name == contentTypeName)
{
message.AppendLine(" Content Type Exists.");
message.AppendLine(" ID = " + ct.Id.ToString());
}//end of if
}//end of foreach
}//end of method
Result:

As you can see, the root web’s content type collection has 67 content types (most of them are ootb content types), the subsite has none (but in real life, has access to the parent web’s 67 content types), and the List has 2 (one of which is the “CustomItem” content type).
But, wait! There’s one more conclusion that we can pull from this result. Notice that the ID for the “CustomItem” content type in the root web and the ID for the “CustomItem” content type in the list are different. This is because the former is a Site Content Type, and the latter is a List Content Type.
Furthermore (!), the List Content Type inherits from the Site Content Type. You can see this by analyzing the two IDs. Notice that the first half of the List Content Type’s ID is the same as the Site Content Type’s ID. The List Content Type’s ID is then followed by “00”, indicating inheritance, and then the List Content Type’s own unique Guid (DF8C713906C23741BA992F91B4587654).
Lastly, we know from this, that the SPContentType object found in the list’s Content Type list can and does in fact represent the List Content Type, not its parent, the Site Content Type.
Final Thoughts:
Although I ran the code as a workflow, this phenomena could also have been demonstrated through a console application, ran on the server.
By: Arjun Chakraborty