The aim of the SharePoint data access
platform, and indeed of SharePoint itself, is to provide a web-based
tool that can be easily customized by end users to store any business
data, either in raw database-style by using custom lists or embedded in
documents by using document libraries and features such as Excel
Services. At the fundamental level, both of these approaches have a
common implementation in the form of content types. Basically, a content type is a metadata definition of a particular type of content.
1. Content Type Inheritance
One important feature of content types is inheritance.
In SharePoint, all content types inherit properties from the System
content type, and when users create new content types, they must select
an appropriate parent content type from which to inherit.
You can see from the hierarchy shown in Figure 1
that custom list data can be stored by creating a content type that
inherits from the Item content type whereas documents can be stored by
using the appropriate Document content type or by creating a new
content type that inherits from Document.
Content Type Identifiers
One thing that may be apparent from Figure 1
is the use of concatenated unique identifiers for each content type.
For example, the identifier for the Master Page content is type is
0x010105, which is shown in Figure 2.
Although from a development perspective, the use of
concatenated identifiers may seem a bit archaic and prone to data entry
errors, there is a very good reason for taking this approach as opposed
to the more traditional technique of assigning automatically generated
sequential identifiers. Practically all of the functionality of the
SharePoint platform is defined at the content type level. For example,
a web page containing web parts is based on the Web Part Page content
type. It is the use of this content type that provides the necessary
data structure required to store the properties of the web parts that
are stored on the page. However, the Web Part Page content type is also
based on the Basic Page content type, and it is via this inheritance
that a physical representation of the page can be rendered from the
database.
Since functionality is effectively layered based on
the content type hierarchy, being able to navigate up and down the
structure efficiently is key to the overall performance of the system.
By using concatenated identifiers, system code can easily derive the
hierarchy without having to resort to database lookups or other methods.
Generating Content Type Identifiers
When programmatically creating content types, you
can use two approaches to generating content type identifiers. The
first approach, which is used by out-of-the-box content types, is to
use this:
Parent content type ID + 2 hexadecimal digits (other than 00, because this is reserved for use by the second method)
For example, if we wanted to create a new content type derived from Master Page, we could use the following identifier:
The second approach, which is recommended when
creating a content type that inherits from a parent that you didn’t
create, is to use this:
Parent content type ID + 00 + hexadecimal GUID
Using the preceding example of a content type derived from Master Page, we could use the following identifier:
The SPContentTypeId Object
To make parsing of content type identifiers easier
in code, the SharePoint object model includes the SPContentTypeId
class. The SPContentTypeId class makes it easy to perform various
actions against content types, such as determining the parent content
type identifier or finding a common parent of two identifiers.
The following code listing shows how to create a
content type programmatically with a user-defined identifier as well as
with a system-defined identifier. You can see that system-defined
identifiers always adopt the lengthier GUID concatenation approach.
static void Main(string[] args)
{
string siteUrl = "http://localhost";
Program p = new Program();
using (SPSite site = new SPSite(siteUrl))
{
using (SPWeb web = site.OpenWeb())
{
Console.WriteLine("{0} | {1} | {2}","Name".PadRight(20),
"ContentTypeId".PadRight(40),
"Parent Name".PadRight(10));
Console.WriteLine(new string(′-′, 78));
SPContentType newContentType;
newContentType=p.CreateContentType(web, "MyFirstContentType", "Item");
Console.WriteLine("{0} | {1} | {2}", newContentType.Name.PadRight(20),
newContentType.Id.ToString().PadRight(40),
newContentType.Parent.Name.PadRight(10));
SPContentTypeId newId = new SPContentTypeId("0x01AB");
newContentType=p.CreateContentType(web, newId, "MySecondContentType");
Console.WriteLine("{0} | {1} | {2}", newContentType.Name.PadRight(20),
newContentType.Id.ToString().PadRight(40),
newContentType.Parent.Name.PadRight(10));
}
}
Console.ReadLine();
}
SPContentType CreateContentType(SPWeb web, string name, string parentName)
{
if (web.AvailableContentTypes[name] == null)
{
SPContentType parent = web.AvailableContentTypes[parentName];
SPContentType contentType = new SPContentType(parent,
web.ContentTypes,
name);
//To save this new content type, update must be called
//contentType.Update();
return contentType;
}
else
{
return web.AvailableContentTypes[name];
}
}
SPContentType CreateContentType(SPWeb web, SPContentTypeId newId,string name)
{
if (web.AvailableContentTypes[newId] == null)
{
SPContentType contentType = new SPContentType(newId,
web.ContentTypes,
name);
//To save this new content type, update must be called
//contentType.Update();
return contentType;
}
else
{
return web.AvailableContentTypes[newId];
}
}
Generally
speaking, performing such actions using code would be required only as
part of the initial setup of a site or site collection.
Content Type Groups
Although all content types are fundamentally derived
from the System content type and exist as part of a well-defined
hierarchy, for ease of reference, content types can also be grouped.
Grouping is purely a metadata activity and has no bearing on content
type inheritance. That said, some groups serve specific purposes within
the SharePoint platform, and one example is the _Hidden group. Content
types belonging to this group are not displayed in the user interface.
Another thing to bear in mind when using
content types is the way in which folders and content hierarchy are
implemented. When creating a document library, you cannot add content
types that are not derived from Document. By the same token, when
you’re creating a custom list, you cannot add content types that are
derived from Document. Notwithstanding
these rules, lists and document libraries can contain content
conforming to many different content types. For example, a document
library can contain Master Pages and Web Part Pages.