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

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

Under no circumstances should you
update the content type definition
file for a content type after you have
installed and activated that content
type. Windows SharePoint Services does
not track changes made to the content
type definition file. Therefore, you
have no method for pushing down
changes made to site content types to
the child content types.

然后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");

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

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

所以,我有几个问题:

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

最佳答案
添加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);

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

转载注明原文:更新已部署的SharePoint内容类型以处理其他项目事件 - 代码日志