更新已部署的SharePoint内容类型以处理其他项目事件

Chr*_*mer 6 deployment sharepoint content-type configuration-management

我有一个网站内容类型,用于整个网站集中的一些列表.在该内容类型中,我描述了一个事件接收器来处理ItemAdding事件.这很好用.现在我需要更新内容类型,以便也处理ItemUpdating.OTTOMH,我尝试简单地修改我的内容类型的xml,因为这似乎允许简单的版本跟踪.这是因为我的更新应用于网站内容类型,但不适用于我使用此内容类型的列表.这是预期的.然后我注意到SharePoint SDK对此有一个严峻的看法:

在安装和激活该内容类型之后,在任何情况下都不应更新内容类型的内容类型定义文件.Windows SharePoint Services不跟踪对内容类型定义文件所做的更改.因此,您无法将对网站内容类型所做的更改推送到子内容类型.

然后SDK指向几个部分,描述如何使用UI或代码推送更改.由于UI不提供事件接收器的挂钩,我想我将选择代码路径.

我以为我可以做这样的事情,只需在列表的内容类型副本中添加一个新的事件接收器:

SPList list = web.Lists["My list"];
SPContentType ctype = list.ContentTypes["My content type"];
// Doesn't work -- EventReceivers is null below.
ctype.EventReceivers.Add(SPEventReceiverType.ItemUpdating, 
                         "My assembly name", "My class name");
Run Code Online (Sandbox Code Playgroud)

但问题是ctype.EventReceivers在这里为null,即使我已经将ItemAdding连接到此列表.它似乎被移动到列表本身.因此,该列表具有有效的EventReceivers集合.

SPList list = web.Lists["My list"];
list.EventReceivers.Add(SPEventReceiverType.ItemUpdating, 
                        "My assembly name", "My class name");
Run Code Online (Sandbox Code Playgroud)

所以,我有几个问题:

  1. 这样做的正确方法是将任何新的事件接收器直接添加到列表中,只是完全忘记我的内容类型?
  2. 要完成此更改,在配置管理方面处理此问题的最佳方法是什么?我应该创建一个简单的控制台应用程序来查找所有适当的列表并修改它们吗?或者以某种方式创建一个功能更好的选择?无论哪种方式,似乎这种变化本身就会发生变化,很难被未来的开发者发现,他们可能需要使用这种内容类型.

Col*_*lin 2

添加EventReceiver后是否调用了ctype.Update(true)?如果不这样做,它就不会被坚持下去。并且不要使用 List 内容类型,而应使用 SPWeb.ContentTypes。

这段代码对我有用:

var docCt = web.ContentTypes[new SPContentTypeId("0x0101003A3AF5E5C6B4479191B58E78A333B28D")];
//while(docCt.EventReceivers.Count > 0)
//  docCt.EventReceivers[docCt.EventReceivers.Count - 1].Delete();
docCt.EventReceivers.Add(SPEventReceiverType.ItemUpdated, "ASSEMBLYNAME, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c5b857a999fb347e", "CLASSNAME");

docCt.Update(true);
Run Code Online (Sandbox Code Playgroud)

true 参数意味着它也会被下推到所有子 ContentType。(即使用内容类型的所有列表)。