当前位置: 首页 > news >正文

SharePoint2010内容类型剖析(四)

更新内容类型

SharePoint允许对内容类型进行修改,即使已经将内容类型部署到网站、列表或已经创建了相应的列表项。


更新内容类型的2条标准途径


途径1:对内容类型进行修改,并推送更新。这条途径主要用在对使用中的内容类型进行有针对性的,离散的变更。比如,需要在网站内容类型上添加一列。
途径2:新建一个内容类型,以满足变更的需求。然后把原来的内容类型加到_Hidden组。这条途径主要用在需要彻底替换原有内容类型,但是还需要保留已有的列表数据的情况下。比如,我们有一个已经用了数年的产品规格内容类型。现在,不得不变更产品的规格,以便体现新的要求。但由于历史的原因,我们仍然要保留原有的产品规格内容类型,因为之前已经有无数的列表项是基于它来创建的。这时,我们可以新建一个内容类型叫产品规格2010。然后通过Feature打包分发,并在激活的代码中通过程序将新的内容类型添加到所有旧内容类型存在的列表中。然后将原来的产品规格内容类型的Hidden属性设为true。这样,当用户创建产品规格时,他们只能选择产品规格2010,原先的产品规格不在列出。但是,原先的列表项却保持不变。


SharePoint提供了一种机制,允许通过改变SPContentType或ContentType对象的ReadOnlySealed属性来控制变更。因此,在修改内容类型前,应该首先检查这些属性设置。

将更新内容类型的代码放在SPFeatureReceiver对象的FeatureActivated(SPFeatureReceiverProperties)方法内。在完成对相应对象中内容类型的修改后,要记得调用该对象的Update方法将变更提交到数据库中。我们可以在Update方法中指定是否要更新子内容类型。


SharePoint并不会将内容类型的更新写回到内容类型定义文件,而是存在SharePoint数据库中。所有的列表内容类型也都是存放在SharePoint数据库中的。因此,任何时候都不要更改已经安装并激活使用的内容类型的定义文件。SharePoint不会跟踪这种变化。

使用对象模型更新内容类型

  • 使用对象模型可以提供更细的推送粒度。
  • 记得调用Update方法将变更写回数据库。
  • 无法通过修改Feature XML文件中的网站内容类型定义来添加栏
ExpandedBlockStart.gif 代码
using  (SPWeb oWebsite  =   new  SPSite( " http://MyServer/sites/MySiteCollection/MyWebSite " ).OpenWeb())
{
    SPList oList 
=  oWebsite.GetList( " MyWebSite/Lists/MyList " );
    SPFieldCollection collFields 
=  oWebsite.Fields;
    
// 新建一个网站栏
     string  strNewColumn  =  collFields.Add( " 出处 " , SPFieldType.Text,  false );
    
// 添加到网站内容类型“消息”中
    SPFieldLink oFieldLink  =   new  SPFieldLink(fields[strNewColumn]);
    SPContentType oContentType 
=  oList.ContentTypes[ " 消息 " ];
    oContentType.FieldLinks.Add(oFieldLink);

    oContentType.Update(
true );
}

内容类型中的自定义信息

  • 按照设计初衷,内容类型是可扩展的。
  • 每个内容类型都有一个XML集,用于存储第三方解决方案中用到的一些信息(XML节点所代表的XmlDocument元素)。通过添加XML节点,可以为内容类型加入自定义信息。通过在内容类型中包含自定义的XmlDocument元素,可以将我们解决方案中所需的自定义信息进行一个封装,使其成为内容类型的一部分。

    可以通过两种方式为内容类型添加自定义信息:
    • 对于已经部署好的内容类型,我们可以通过OM以编程的方式访问该集合中的Xml。只需要调用SPXmlDocumentCollectionAdd方法即可。
    • 对于未进行部署的内容类型,我们可以在内容类型架构定义XML中添加一个XmlDocument元素。

  • 内容类型可以包含任何数目的XmlDocument元素。每个XmlDocument可以有自己的架构,只要是有效的XML即可。
  • 网站内容类型中包含的XmlDocument内容会自动复制到任何子代。推送的粒度也可以基于Xml节点。但是,SharePoint在覆盖该xml节点前不会去判断该节点是否正在被使用或是否为某个处理过程所必需。我们也可以删除某个xml,并作为变更推送下去。

关联工作流

SPContentType.WorkflowAssociations 属性返回一个SPWorkflowAssociationCollection对象代表了内容类型所关联的所有工作流。我们可以通过Id属性或GetAssociationByName方法取到其中某个工作流。每个集合内的工作流的Name是唯一的。通过GetAssociationByName的返回值判断是否重名。
ExpandedBlockStart.gif代码

if  (contentType.WorkflowAssociations.GetAssociationByName(workflowAssociation.Name, site.Locale)  ==   null )
{
    contentType.WorkflowAssociations.Add(workflowAssociation);
}
else
{
    contentType.WorkflowAssociations.Update(workflowAssociation);
}

 

实例:创建一个工作流关联,将其添加到某个网站内容类型的工作流集合,然后推送到子代内容类型
(注意:在新建项目的框架版本选择时要选择.Net Framework 3.5,还需要添加Microsoft.SharePoint.dll的引用)。下图是实例中要用到的工作流模板,首先要确保其已激活。


点击查看大图

 

完成后查看工作流关联,可以看到下图:


点击查看大图

 

以下是添加关联的代码:

ExpandedBlockStart.gif 代码
using  System;
using  Microsoft.SharePoint;
using  Microsoft.SharePoint.Workflow;

namespace  TestWorkflowAssociation
{
    
class  ConsoleAdd
    {
        
static   void  Main( string [] args)
        {
            Console.WriteLine();
            SPSite siteCollection 
=   new  SPSite( " http://sp2010u/sites/contoso/Docs " );
            SPWeb site 
=  siteCollection.OpenWeb();

            SPContentType siteContentType 
=  site.ContentTypes[ " 费用报告 " ];
            
string  taskListTitle  =   " 任务 " ;
            
string  historyListTitle  =   " 工作流历史记录 " ;
            
string  workflowName  =   " 红-黄-绿 " ;

            
//  获取一个模板.
            SPWorkflowTemplate workflowTemplate  =   null ;
            
foreach  (SPWorkflowTemplate template  in  site.WorkflowTemplates)
            {
                workflowTemplate 
=  template;

                
//  这里找一个自带的模板.
                 if  (workflowTemplate.Name  ==   " 三态 " break ;
            }
            
if  (workflowTemplate  !=   null )
            {
                
//  创建一个关联.
                SPWorkflowAssociation workflowAssociation  =  SPWorkflowAssociation.CreateWebContentTypeAssociation(workflowTemplate, workflowName, taskListTitle, historyListTitle);


                
//  添加一个关联到该内容类型,如果关联已存在则更新它.
                Console.Write( " 工作流 {0} 已关联  " , workflowAssociation.Name);
                
if  (siteContentType.WorkflowAssociations.GetAssociationByName(workflowAssociation.Name, site.Locale)  ==   null )
                {
                    siteContentType.WorkflowAssociations.Add(workflowAssociation);
                    Console.WriteLine(
" 添加. " );
                }
                
else
                {
                    siteContentType.WorkflowAssociations.Update(workflowAssociation);
                    Console.WriteLine(
" 更新. " );
                }

                
//  将工作流关联更新推送到子代内容类型.
                siteContentType.UpdateWorkflowAssociationsOnChildren( false ,   //  不需要生成完整变更清单
                                                                      true ,    //  推送到继承的子代网站内容类型
                                                                      true ,    //  推送到列表内容类型
                                                                      false );  //  如果遇到密封或只读内容类型不抛异常  
            }
            site.Dispose();
            siteCollection.Dispose();

            Console.WriteLine();
            Console.Write(
" 任意键继续... " );
            Console.ReadLine();
        }
    }
}

以下代码删除刚才关联的工作流:

ExpandedBlockStart.gif 代码
using  System;
using  Microsoft.SharePoint;
using  Microsoft.SharePoint.Workflow;

namespace  TestWorkflowAssociation
{
    
class  ConsoleDel
    {
        
static   void  Main( string [] args)
        {
            
using  (SPSite site  =   new  SPSite( " http://sp2010u/sites/contoso/Docs " ))
            {
                
using  (SPWeb web  =  site.OpenWeb())
                {
                    
string  ctName  =   " 费用报告 " ;
                    
string  wfName  =   " 红-黄-绿 " ;

                    SPContentType contentType 
=  web.ContentTypes[ctName];
                    
if  ( null   !=  contentType)
                    {
                        SPWorkflowAssociation wfAssociation 
=
                            contentType.WorkflowAssociations.GetAssociationByName(wfName, web.Locale);

                        
if  ( null   !=  wfAssociation)
                        {
                            
//  移除该工作流关联.
                            contentType.WorkflowAssociations.Remove(wfAssociation);
                            Console.WriteLine(
" 与工作流 {0} 的关联已移除. " , wfAssociation.Name);
                        }
                        
else
                        {
                            Console.WriteLine(
" 名为 {0} 的工作流关联未找到. " , wfName);
                        }
                    }
                    
else
                    {
                        Console.WriteLine(
" 内容类型 {0} 不存在. " , ctName);
                    }
                    
//  将工作流关联更新推送到子代内容类型.
                    contentType.UpdateWorkflowAssociationsOnChildren( false true true false ); 
                }
            }
            Console.Write(
" \n任意键继续... " );
            Console.ReadLine();
        }
    }
}

内容类型XML架构定义

  • 应用一:可以在Feature中通过内容类型的SchemaXml 新建一个内容类型定义。
  • 应用二:可以通过List定义中的ContentTypes元素在创建列表时自动附加一个已有的内容类型

网站内容类型定义中引用的栏或内容类型可以包含在另一个Feature里。这种情况下,我们要注意创建相应的激活依赖性

 

内容类型架构定义位于C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\XML\wss.xsd


点击查看大图

 

可以打开ctypewss.xml(位于%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\14\TEMPLATE\FEATURES\ctype)。其中包含了大多数SharePoint内置的内容类型定义。我们可以将其做为一个很好的学习内容类型架构的例子。


点击查看大图

转载于:https://www.cnblogs.com/Sunmoonfire/archive/2010/05/19/1738815.html

相关文章:

  • 自定义异常--老是忘记 exception
  • 控制钱箱,客显,打印
  • [JS7] 显示从0到99的100个数字
  • 我们不是客户
  • GHOST系统后,蓝屏代码为0x0000007B解决方法
  • xvhfeng的工作回忆总结(第三年)
  • Entity Framework Core 2.0的突破性变更
  • shell脚本编写 之 条件选择,条件判断,循环语句
  • EF架构~mysql数据库无法创建数据模型
  • 解决SecureCRT中文显示乱码
  • dbvis增加oralc连接
  • 在windows平台上搭建Android开发环境-图例
  • Reactive Programming with Spring 5
  • IIS6.0下创建用户隔离模式FTP站点
  • Hadoop如何迎击大数据分析的挑战
  • AWS实战 - 利用IAM对S3做访问控制
  • CentOS6 编译安装 redis-3.2.3
  • FastReport在线报表设计器工作原理
  • Git学习与使用心得(1)—— 初始化
  • java中具有继承关系的类及其对象初始化顺序
  • Linux后台研发超实用命令总结
  • Logstash 参考指南(目录)
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • PAT A1050
  • SQLServer之索引简介
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • Vue2.0 实现互斥
  • vue--为什么data属性必须是一个函数
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 今年的LC3大会没了?
  • 推荐一个React的管理后台框架
  • 学习Vue.js的五个小例子
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • 中文输入法与React文本输入框的问题与解决方案
  • nb
  • NLPIR智能语义技术让大数据挖掘更简单
  • raise 与 raise ... from 的区别
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • ​2021半年盘点,不想你错过的重磅新书
  • ​Spring Boot 分片上传文件
  • # 数据结构
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (4)Elastix图像配准:3D图像
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (七)Knockout 创建自定义绑定
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .net 简单实现MD5