内容类型的创建与维护通常都在网站层次上进行。当新内容类型创建并添加到网站内容类型集合后,它是一个网站内容类型。此时该内容类型可以被添加到列表或文档库,但是还没有被添加。当我们将一个网站内容类型添加到列表时,SharePoint会生成一个该网站内容类型的本地副本,并将该副本添加到列表。这个本地的实例被称为列表内容类型。它只能用在该列表内。默认列表内容类型:SharePoint里的每个项都必然会属于一个内容类型。这可能是显性的也可能是隐性的。对未允许内容类型的列表栏的更改实际上发生在其默认列表内容类型上。
内置的内容类型分了很多组。如下图所示:
通过内容类型对象的Group属性获取所属分组。_Hidden组的内容类型不会显示在UI中。也就无法派生或添加到列表中
内容类型的ID用于在网站集内唯一标识内容类型,并设计为可递归。ID封装了该内容类型的血统,或者说是从父内容类型到该内容类型的一条继承线。每个内容类型的ID都包含了父内容类型的ID,一次类推,直到系统内容类型的ID。推送操作正式基于此。可以基于以下两个公约之一构造一个有效的内容类型ID。两者强调的重点不同,一个强调简洁,一个强调独特。可根据具体情况选择。
父内容类型ID + 两位16进制值(“00”除外)。通常默认的内容类型都是采用这种方式。父内容类型ID + “00” + 16进制的GUID。通常我们继承的网站内容类型和列表内容类型都是采用这种方式。通常我们的自定义解决方案中推荐使用这种方式。以保证唯一性。但对于其子代,推荐使用上一种方式,这样可以有效减少ID的长度,以保证可以继承的代数。因为ID的长度是有一个512字节的限制。由于一个字节可以存放两位16机制值,所以内容类型ID不能大于1024个字符。
下图展示了SharePoint自带的文档内容类型的ID,以及基于两种公约进行的一些ID继承变化:
例子:获取网站内容类型——“项目”有多少子代。统计其被其他网站内容类型和列表内容类型继承的次数。
代码 using System; using System.Collections.Generic; using Microsoft.SharePoint; namespace Test{ class ConsoleApp { static void Main( string [] args) { using (SPSite siteCollection = new SPSite( " http://sp2010u/sites/contoso " )) { using (SPWeb rootWeb = siteCollection.RootWeb) { // 获取内容类型 SPContentType contentType = rootWeb.AvailableContentTypes[SPBuiltInContentTypeId.Item]; // 获取使用情况的集合. IList < SPContentTypeUsage > usages = SPContentTypeUsage.GetUsages(contentType); // 对网站内容类型和列表内容类型进行计数. int listTypes = 0 ; int siteTypes = 0 ; foreach (SPContentTypeUsage usage in usages) { if (usage.IsUrlToList) listTypes ++ ; else siteTypes ++ ; } Console.Write( " The content type is inherited by {0} site content types " , siteTypes); Console.WriteLine( " and {0} list content types. " , listTypes); } } Console.Write( " \nPress ENTER to continue... " ); Console.ReadLine(); } }}
在我的环境中的运行结果如下:
The content type is inherited by 80 site content types and 126 list content types. Press ENTER to continue...当我们在代码中创建内容类型时,不必为它编个ID。相反,我们可以让系统基于父ID自动生成。
如下面的控制台应用程序所示,从项目内容类型派生出一个新的客户内容类型。并添加到网站内容类型集合中。然后又将该内容类型附加到某个列表内容类型集合上。最后,比较全部3个内容类型的ID:顺序为父内容类型,新的网站内容类型,新的列表内容类型。
代码 using System; using Microsoft.SharePoint; namespace Test{ class ConsoleCTId { static void Main( string [] args) { using (SPSite site = new SPSite( " http://sp2010u/sites/contoso " )) { using (SPWeb web = site.OpenWeb()) { // 获得网站内容类型——项目 SPContentType parentCType = web.AvailableContentTypes[SPBuiltInContentTypeId.Item]; // 创建一个新的内容类型——客户,派生自项目. SPContentType childCType = new SPContentType(parentCType, web.ContentTypes, " 客户 " ); // 将新的内容联系添加到网站内容类型集合 childCType = web.ContentTypes.Add(childCType); // 添加到一个列表. SPList list = web.Lists[ " 通知 " ]; list.ContentTypesEnabled = true ; SPContentType listCType = list.ContentTypes.Add(childCType); // 输出全部的3个ID. Console.WriteLine( " Parent content type ID: {0} " , parentCType.Id.ToString()); Console.WriteLine( " Site content type ID: {0} " , childCType.Id.ToString()); Console.WriteLine( " List content type ID: {0} " , listCType.Id.ToString()); } } Console.Write( " \nPress ENTER to continue... " ); Console.ReadLine(); } }}
在我的环境中的运行结果如下:
Parent content type ID: 0x01 Site content type ID: 0x0100B0B200027F78F54CAA7B1095536B3DE4 List content type ID: 0x0100B0B200027F78F54CAA7B1095536B3DE40041C512D9D0D61741A4239F25B2988C48 Press ENTER to continue...SPContentType构造器也可以通过SPContentTypeId方式创建。此时,其Parent属性的值实际上是通过分析所传递的内容类型ID而得到的。
代码中的注释很详细,就不多废话了:
代码 using System; using System.Collections; using Microsoft.SharePoint; namespace Test{ class ConsoleCTGroup { static void Main( string [] args) { using (SPSite site = new SPSite( " http://sp2010u/sites/contoso " )) { using (SPWeb web = site.OpenWeb()) { // 创建一个内容类型的可排序列表. ArrayList list = new ArrayList(); foreach (SPContentType ct in web.AvailableContentTypes) list.Add(ct); // 以组名排序. list.Sort( new CTComparer()); // 输出. Console.WriteLine( " {0,-35} {1,-12} {2} " , " Site Content Type " , " Parent " , " Content Type ID " ); for ( int i = 0 ; i < list.Count; i ++ ) { SPContentType ct = (SPContentType)list[i]; if (i == 0 || ((SPContentType)list[i - 1 ]).Group != ct.Group) { Console.WriteLine( " \n{0} " , ct.Group); Console.WriteLine( " ------------------------ " ); } Console.WriteLine( " {0,-35} {1,-12} {2} " , ct.Name, ct.Parent.Name, ct.Id); } } } Console.Write( " \nPress ENTER to continue... " ); Console.ReadLine(); } } // 基于 IComparer 接口实现比较操作. // 先通过组名比较,然后通过内容类型Id比较. class CTComparer : IComparer { // 实现 Compare 方法. int IComparer.Compare( object x, object y) { SPContentType ct1 = (SPContentType)x; SPContentType ct2 = (SPContentType)y; // 首先比较组名 . int result = string .Compare(ct1.Group, ct2.Group); if (result != 0 ) return result; // 如果组名相同, 比较ID. return ct1.Id.CompareTo(ct2.Id); } }}
重点掌握实现的思路。
转载于:https://www.cnblogs.com/Sunmoonfire/archive/2010/05/17/1737290.html
相关资源:数据结构—成绩单生成器