SharePoint2010内容类型剖析(四)
更新內容類型
SharePoint允許對內容類型進行修改,即使已經將內容類型部署到網站、列表或已經創建了相應的列表項。
更新內容類型的2條標準途徑
途徑1:對內容類型進行修改,并推送更新。這條途徑主要用在對使用中的內容類型進行有針對性的,離散的變更。比如,需要在網站內容類型上添加一列。
途徑2:新建一個內容類型,以滿足變更的需求。然后把原來的內容類型加到_Hidden組。這條途徑主要用在需要徹底替換原有內容類型,但是還需要保留已有的列表數據的情況下。比如,我們有一個已經用了數年的產品規格內容類型。現在,不得不變更產品的規格,以便體現新的要求。但由于歷史的原因,我們仍然要保留原有的產品規格內容類型,因為之前已經有無數的列表項是基于它來創建的。這時,我們可以新建一個內容類型叫產品規格2010。然后通過Feature打包分發,并在激活的代碼中通過程序將新的內容類型添加到所有舊內容類型存在的列表中。然后將原來的產品規格內容類型的Hidden屬性設為true。這樣,當用戶創建產品規格時,他們只能選擇產品規格2010,原先的產品規格不在列出。但是,原先的列表項卻保持不變。
SharePoint提供了一種機制,允許通過改變SPContentType或ContentType對象的ReadOnly 和Sealed屬性來控制變更。因此,在修改內容類型前,應該首先檢查這些屬性設置。
將更新內容類型的代碼放在SPFeatureReceiver對象的FeatureActivated(SPFeatureReceiverProperties)方法內。在完成對相應對象中內容類型的修改后,要記得調用該對象的Update方法將變更提交到數據庫中。我們可以在Update方法中指定是否要更新子內容類型。
SharePoint并不會將內容類型的更新寫回到內容類型定義文件,而是存在SharePoint數據庫中。所有的列表內容類型也都是存放在SharePoint數據庫中的。因此,任何時候都不要更改已經安裝并激活使用的內容類型的定義文件。SharePoint不會跟蹤這種變化。
使用對象模型更新內容類型
- 使用對象模型可以提供更細的推送粒度。
- 記得調用Update方法將變更寫回數據庫。
- 無法通過修改Feature XML文件中的網站內容類型定義來添加欄
{
????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。只需要調用SPXmlDocumentCollection的Add方法即可。
- 對于未進行部署的內容類型,我們可以在內容類型架構定義XML中添加一個XmlDocument元素。
- 內容類型可以包含任何數目的XmlDocument元素。每個XmlDocument可以有自己的架構,只要是有效的XML即可。
- 網站內容類型中包含的XmlDocument內容會自動復制到任何子代。推送的粒度也可以基于Xml節點。但是,SharePoint在覆蓋該xml節點前不會去判斷該節點是否正在被使用或是否為某個處理過程所必需。我們也可以刪除某個xml,并作為變更推送下去。
關聯工作流
SPContentType.WorkflowAssociations 屬性返回一個SPWorkflowAssociationCollection對象代表了內容類型所關聯的所有工作流。我們可以通過Id屬性或GetAssociationByName方法取到其中某個工作流。每個集合內的工作流的Name是唯一的。通過GetAssociationByName的返回值判斷是否重名。
代碼
{
????contentType.WorkflowAssociations.Add(workflowAssociation);
}
else
{
????contentType.WorkflowAssociations.Update(workflowAssociation);
}
?
實例:創建一個工作流關聯,將其添加到某個網站內容類型的工作流集合,然后推送到子代內容類型
(注意:在新建項目的框架版本選擇時要選擇.Net Framework 3.5,還需要添加Microsoft.SharePoint.dll的引用)。下圖是實例中要用到的工作流模板,首先要確保其已激活。
點擊查看大圖
?
完成后查看工作流關聯,可以看到下圖:
點擊查看大圖
?
以下是添加關聯的代碼:
代碼 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();
????????}
????}
}
以下代碼刪除剛才關聯的工作流:
代碼 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
總結
以上是生活随笔為你收集整理的SharePoint2010内容类型剖析(四)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ZooKeeper学习-- Zookee
- 下一篇: IIS支持Shtml后辍文件方法