zoukankan      html  css  js  c++  java
  • MOSS中创建自定义内容类型

    一:简要介绍

    某类内容的一组可重用设置,使用内容类型可一致管理元数据,模板以及项目和文档的行为。内容类型在网站级别定义并用于列表和库。站点内容类型是可以独立于任何特定站点集合、站点、列表或文档库而建立的元数据定义。

    MOSS系统提供的在 %CommonProgramFiles%\Microsoft Shared\Web Server Extensions\12\Template\Features\Ctypes 文件夹中定义,你可以查看该文件夹中的ctypeswss.xml文件包含所有内容类型的定义。

    二:系统内容类型

    <ContentType ID="0x"
    Name="$Resources:System"
    Group="_Hidden"
    Sealed="TRUE"
    Version="0">
    <FieldRefs>
    <FieldRef ID="{c042a256-787d-4a6f-8a8a-cf6ab767f12d}" Name="ContentType"/>
    </FieldRefs>
    </ContentType>

    在ctypeswss.xml文件中的第一个内容类型为System,所有的内容类型最终都是从System内容类型继承而来的,从下图可以清晰的看出:

    ct1

    三:内容类型的ID

    上图右边代表内容类型的ID,每一个内容类型都有一个ID的属性,这个ID是内容类型的唯一标识,每一个内容类型的ID都包括他父内容类型的ID,所以所有内容类型的前两位就是Sytem内容类型的ID,这样我们就可以通过解析内容类型的id来分析内容类型的继承体系。

    内容类型的ID有两种命名的方式:

    1. 父内容类型ID+两个十六进制数(不包括”00”)

    2. 父内容类型id+“00”+十六进制的GUID

    这里System内容类型是个特例,他的id是“0x”,其他的内容类型必须遵守上面两种约定的一种。第一种由于只包括两个十六进制数所以他强调的是id的简洁性,第二种包括GUID强调的是该内容类型的唯一性。每一种都有适合的情况。

    父内容类型ID+两个十六进制数(不包括”00”)

    Wss一般使用这种方式来生成默认的内容类型,比如基本的内容类型Item的id是0x01,Item是System的儿子,Document的id是0x0101,folder的id是0x0120,通过解析id你可以看出Document和folder都是Item的儿子,如下图:

    clip_image004

    ct2

    父内容类型id+“00”+十六进制的GUID

    Wss使用这种命名id的方式创建内容类型主要在以下两种情况

    1. 站点内容类型(基于其他类型创建的)

    2. 列表类型(将站点类型添加到列表中时,得到的站点类型实例的拷贝)

    例如有一个内容类型的id是"0x010100D5C2F139516B419D801AC6C18942554D",通过这个id可以看出以下两点:

    1. 是Document内容类型的直接基础而来的。

    2. 当Document内容类型被填加到列表时一个列表内容类型被创建,。

    当父类型是以下情况时,我们推荐你使用GUID的方式创建内容类型的id

    1. 父类型为wss默认的内容类型,比如Document

    2. 通过第三方工具开发的内容类型,这种你要确定第三方开发的内容类型和wss默认提供的没有冲突。

    内容类型id的长度最大是512bytes即不能超过 1,024 个字符。由于有这个限制我们的id命名可以根据需要灵活的去控制,否则就会出现超出的情况。

    四:创建自定义内容类型

    1. 我们创建一个基于Event类型的自定义内容类型,项目结构如下图:

    ct3

    2. OnlineEvent.xml文件是内容类型的定义文件,每一个Field节点代表不同的网站栏,FieldRef节点代表网站栏在该内容类型中的引用。我们定义了四个网站栏分别为Status Field,Number Of Attendees,Event Type,Audience Type。具体代码如下:

    <?xml version="1.0" encoding="utf-8"?>
    
    <Elements Id="5f0c1259-87bc-4d63-bfc8-6f4997ec3f20" xmlns="http://schemas.microsoft.com/sharepoint/">
    <ContentType ID="0x010200730061eb7d784bb786f4ac157702b8c7" Name="OnlineEvent" Group="Development" 
    Description="Developing Content Type" Version="0"> <FieldRefs> <FieldRef ID="{5FCA124E-66FD-4e70-B3CE-D4B7C97D8A0E}" Name="StatusField"
    DisplayName="Status Field" Required="TRUE" /> <FieldRef ID="{9451F129-78A1-47f0-8CA5-AB7F0D51902C}" Name="NumberOfAttendeesField"
    DisplayName="Number Of Attendees" Required="FALSE" /> <FieldRef ID="{63DF93F8-B6E8-4c66-A1CB-66C1E677AF45}" Name="EventTypeField"
    DisplayName="Event Type" Required="TRUE" /> <FieldRef ID="{2071EA0D-3F61-4de4-9A68-7C9C1047AC19}" Name="AudienceTypeField"
    DisplayName="Audience Type" Required="TRUE" /> </FieldRefs> </ContentType> <Field ID="{5FCA124E-66FD-4e70-B3CE-D4B7C97D8A0E}" Type="Choice" Name="StatusField"
    DisplayName="Status" StaticName="StatusField" Hidden="FALSE" Required="TRUE" Sealed="FALSE"> <CHOICES> <CHOICE>None</CHOICE> <CHOICE>Approved </CHOICE> <CHOICE>Rejected</CHOICE> </CHOICES> <Default>None</Default> </Field> <Field ID="{9451F129-78A1-47f0-8CA5-AB7F0D51902C}" Type="Number" Name="NumberOfAttendeesField"
    DisplayName="Number Of Attendees" StaticName="NumberOfAttendeesField" Hidden="FALSE" Required="FALSE" Sealed="FALSE" /> <Field ID="{63DF93F8-B6E8-4c66-A1CB-66C1E677AF45}" Type="Choice" Name="EventTypeField"
    DisplayName="Event Type" StaticName="EventTypeField" Hidden="FALSE" Required="TRUE" Sealed="FALSE"> <CHOICES> <CHOICE>Business/Career</CHOICE> <CHOICE>Classes &amp; Lectures</CHOICE> <CHOICE>Dinners/Galas</CHOICE> <CHOICE>Fundraiser</CHOICE> <CHOICE>Misc</CHOICE> <CHOICE>Seminars</CHOICE> <CHOICE>Support Groups</CHOICE> </CHOICES> </Field> <Field ID="{2071EA0D-3F61-4de4-9A68-7C9C1047AC19}" Type="MultiChoice" Name="AudienceTypeField"
    DisplayName="Audience Type" StaticName="AudienceTypeField" Hidden="FALSE" Required="TRUE" Sealed="FALSE"> <CHOICES> <CHOICE>Adults</CHOICE> <CHOICE>Everyones' Invited</CHOICE> <CHOICE>Families</CHOICE> <CHOICE>Kids</CHOICE> <CHOICE>Men</CHOICE> <CHOICE>Seniors</CHOICE> <CHOICE>Singles</CHOICE> <CHOICE>Teens</CHOICE> <CHOICE>Women</CHOICE> </CHOICES> </Field> </Elements>

    3.部署完成后我们去“网站设置—网站内容类型库”中即可以看到,下面是部分截图:

    ct4

    其中的标题,地点,开始时间等都是由Event继承而来的。

    4.我们新创建一个日历的列表,然后去“设置—列表设置—高级设置”中设置为允许管理内容类型,如下图:

    ct5

    5.然后该日历列表的设置面板里就会出现内容类型的设置,如下图:

    ct6

    6.我们点击“从现有网站内容类型添加”来把我们刚才自定义的内容类型OnlineEvent添加进来,并删除原来的事件内容类型。

    7.这时我们返回日历列表,点击新建就会使用我们自定义的内容类型来创建,如下图“

    ct7

    8.如果现在我们创建OnlineEvent内容类型的项目他会使用MOSS本身的样式,MOSS本身使用NewForm.aspx ,EditForm.aspx,DispForm.aspx。每一个页面都包含一个ListFormWebPart。接着我们就创建自定义的新建,编辑和显示页面,OnlineEventAdd.aspx,OnlineEventDisplay.aspx,OnlineEventEdit.aspx分别对应新建,显示和编辑页面,相应的.cs文件为他们后台的代码文件。

    我们在新建,显示和编辑页面时他们产生的URL是有一定规律的,例

    http://carysun/_layouts/ONLINEEVENT/OnlineEventAdd.aspx?List=22c18dec%2D33f7%2D42eb%2D9632%2D630384b99e52&RootFolder=%2FLists%2FCalendar&ContentTypeId=0x010200730061EB7D784BB786F4AC157702B8C70010F7F00BE575CB40AA1B113235A36982&Source=http%3A%2F%2Fcarysun%2FLists%2FCalendar%2Fcalendar%2Easpx

    主要包括以下几部分:

    List:列表的id

    ID:这个条目的ID

    Source: 返回的URL

    我们使用SetValues方法来给相应的item赋值,注意最后一定要调用Update方法来更新。

    protected bool SetValues()
    {
         SPWeb web = SPContext.Current.Web;
         web.AllowUnsafeUpdates = true;
         SPListItem item = SPContext.Current.Item as SPListItem;
    
         if (item != null)
         {
            if (!Page.IsValid) return false;
            item[FLD_TITLE] = txtTitle.Text;
            item[FLD_LOCATION] = txtLocation.Text;
            item[FLD_STARTTIME] = spDTStartTime.Value;
            item[FLD_ENDTIME] = spDTEndTime.Value;
            item[FLD_NUMBER_OF_ATTENDEES] = nfAttendees.Value;
            item[FLD_EVENTTYPE] = ddEventType.Value;
            item[FLD_AUDIENCETYPE] = ccAudienceType.Value;
            item[FLD_DESCRIPTION] = rhTxtDescription.Value;
            item[FLD_STATUS] = ddStatus.Value;
            item.Update();
        }
        return true;
    }

    具体的代码请参考附件中的源代码。

    9.我们要在OnlineEvent.xml中添加如下设置来指定使用我们自定义的页面:

    <XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
    <FormUrls xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
    <Edit>_layouts/ONLINEEVENT/OnlineEventEdit.aspx</Edit>
    <New>_layouts/ONLINEEVENT/OnlineEventAdd.aspx</New>
    <Display>_layouts/ONLINEEVENT/OnlineEventDisplay.aspx</Display>
    </FormUrls>
    </XmlDocument>

    10.填加EventHandler事件处理程序,在新建和更新的时候判断来保证该列表中的项目标题不能重复,我们需要重写ItemAdding和ItemUpdating,代码如下:

    public override void ItemAdding(SPItemEventProperties properties)
    {
         using (SPSite site = new SPSite(properties.WebUrl))
         {
             using (SPWeb web = site.OpenWeb())
             { 
                 SPList list = (web.Lists[properties.ListId]);
                 string theTitle = (string)properties.AfterProperties["Title"];
                 if (findItemWithTitle(theTitle, -1, list))
                 {
                     properties.ErrorMessage =
                                   string.Format("A title of {0} is already in use", theTitle);
                     properties.Cancel = true;
                 }
             }
         }
    }
    
    public override void ItemUpdating(SPItemEventProperties properties)
    {
        SPListItem item = properties.ListItem;
        SPList list = item.ParentList;
        string theTitle = (string)properties.AfterProperties["Title"];
        if (findItemWithTitle(theTitle, item.ID, list))
        {
           properties.ErrorMessage =
                                string.Format("A title of {0} is already in use", theTitle);
           properties.Cancel = true;
        }
    
    }
    
    private bool findItemWithTitle(string title, int id, SPList list)
    {
         string camlQuery = @"
                  <Where> <And> <Eq> <FieldRef Name='LinkTitle' />
                          <Value Type='Text'>{0}</Value></Eq><Neq>
                          <FieldRef Name='ID' /><Value Type='Counter'>{1}
    </Value></Neq></And> </Where>"; SPQuery query = new SPQuery(list.DefaultView); query.Query = string.Format(camlQuery, title, id); SPListItemCollection results = list.GetItems(query); return (results.Count > 0); }

    重新编译后OnlineEvent.xml中会自动填加如下部分:

    <XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/events">
    <Receivers>
    <Receiver>
    <Name>ItemAdding</Name>
    <Type>ItemAdding</Type>
    <SequenceNumber>1</SequenceNumber>
    <Class>5109fd1e-10f1-4f27-9448-b06dc140ec78</Class>
    </Receiver>
    <Receiver>
    <Name>ItemUpdating</Name>
    <Type>ItemUpdating</Type>
    <SequenceNumber>1</SequenceNumber>
    <Class>5109fd1e-10f1-4f27-9448-b06dc140ec78</Class>
    </Receiver>
    </Receivers>
    </XmlDocument>

    成功部署后我们自定义的页面如下图

    ct8

    如果我新建的项目的标题和现有的冲突就会有如下提示:

    ct9

    代码下载:CustomContentTypesDemo

    作者:生鱼片
             
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Java基础——Instanceof 运算符
    算法——八皇后问题(eight queen puzzle)之回溯法求解
    浅析数据结构
    react給變量賦值并列元素
    如何使用npm构建一个react demo项目
    Java面试题 静态代码块 构造代码块 构造方法 的执行顺序
    Mysql 反向解析 导致远程访问慢
    Django admin管理工具
    Django-Ajax(85)
    jQuery快速入门
  • 原文地址:https://www.cnblogs.com/carysun/p/ContentTypes.html
Copyright © 2011-2022 走看看