MOSS 开发人员 - 第 3 部分:开发人员的事件处理程序
从开发人员的角度提供了事件处理程序的概述。此内容是 www.myrampup.com MOSS 内容的第三部分。
本文及其在 MSDN 上的原始文章均为 Microsoft 服务器/工具部门的财产,并经其许可发布。
引言
Windows SharePoint Services 2.0 引入了通过将 Microsoft .NET 程序集附加到文档库,从 Windows SharePoint Services 2.0 文档库中触发的接收事件。然而,事件接收仅限于文档库或表单库,并且事件仅在库中实际操作发生后才触发。Windows SharePoint Services 3.0 更进一步,引入了一套新的、广泛的事件,您不仅可以在库中使用,现在还可以在列表、站点和用户操作中使用。
Windows SharePoint Services 3.0 中的事件现在支持以下功能:
- 您可以使用前同步和后异步模式来处理事件。
- 您可以在文件、列表和网站级别注册事件。
- 每个项目可以注册多个事件。
- 您可以取消前同步事件并显示自定义错误消息。
- 您可以在通用列表以及文档库上注册项目事件。
- 您可以按列表类型或内容类型声明性地注册事件。
- 除了捕获标准列表项事件(例如,ItemAdding、ItemDeleting 或 ItemUpdating),您还可以捕获架构事件(例如添加、删除或更新列)以及网站和网站集删除事件。
创建基本事件处理程序
以下示例展示了创建事件处理程序的基本步骤,该处理程序在删除列表项之前或添加项之后执行代码。该示例适用于公告列表,它会向新项的正文添加文本,但会取消删除现有项的尝试。
您可以通过创建类库在 Microsoft Visual Studio 2005 中创建事件处理程序程序集。您添加对 Microsoft.SharePoint.dll 的引用,并从 Microsoft.SharePoint.SPItemEventReceiver 基类继承。
当列表中发生操作时,Windows SharePoint Services 3.0 会实例化您的类的对象。作为开发人员,您将覆盖 SharePoint 基类中您感兴趣处理的事件的方法。您可以覆盖的 SPItemEventReceiver 类的方法如下:
- ContextEvent
- ItemAdded
- ItemAdding
- ItemAttachmentAdded
- ItemAttachmentAdding
- ItemAttachmentDeleted
- ItemAttachmentDeleting
- ItemCheckedIn
- ItemCheckedOut
- ItemCheckingIn
- ItemCheckingOut
- ItemDeleted
- ItemDeleting
- ItemFileConverted
- ItemFileMoved
- ItemFileMoving
- ItemUncheckedOut
- ItemUncheckingOut
- ItemUpdated
- ItemUpdating
该示例重写了两个方法:ItemDeleting 和 ItemAdded。请记住,后缀“ing”表示我们以同步方式在操作实际发生之前处理事件,而后缀“ed”表示我们以异步方式在操作发生之后处理事件。
当您的方法被调用时,您可以通过作为输入参数提供的对象访问与 SPListItem 对象关联的数据。此对象类型为 SPItemEventProperties。通过 SPItemEventProperties 类的 Cancel 属性,您可以取消事件;通过 ErrorMessage 属性,您可以在 SharePoint 页面上显示自定义错误消息。
第二个要重写的方法是 ItemAdded。以下示例使用 ListItem 属性返回表示新列表项的对象,然后修改该项的正文文本。
您必须注册 ItemDeleting 和 ItemAdded 事件接收器,具体操作请参见 注册事件处理程序。
注册事件处理程序
由于 Windows SharePoint Services 3.0 引入了内容类型和功能等新概念,因此事件处理程序的注册方式有所不同。但是,为了向后兼容,Windows SharePoint Services 3.0 支持现有的库事件注册。EventSinkAssembly、EventSinkClass 和 EventSinkData 属性继续发挥作用,并在用户界面中公开。
在 Windows SharePoint Services 3.0 中,有三种基本方法来注册事件处理程序:
- 通过对象模型,因为 SPWeb 和 SPList 类现在都提供了一个 EventReceivers 属性,通过该属性可以访问网站或列表的事件接收器定义集合。您可以通过调用 Add 方法添加新的事件接收器。
- 按列表类型声明性地,例如,为所有公告列表注册事件处理程序。在 Feature.xml 文件中,您可以通过列表模板 ID 注册事件处理程序。当包含功能按 SPWeb 对象激活时,您可以为指定类型的任何列表注册事件处理程序。
- Feature.xml 您使用此 XML 文件定义新功能的元数据。以下示例代码将功能范围限定在网站级别,并为新功能定义了一个唯一标识符。然后,使用 ElementManifests 元素,它指向存储所有功能详细信息的第二个 XML 文件的位置。
- Elements.xml 您使用此文件定义封装事件处理程序的程序集、类本身,以及一个序列号,该序列号指定了当多个事件处理程序与该功能关联时它们的顺序。以下示例注册了用于删除和添加项目的事件接收器。
注意 包含您的事件处理程序的程序集必须具有强名称并在全局程序集缓存 (GAC) 中注册才能使用。您不能从 \_app_bin 文件夹(本地驱动器:\Inetpub\wwwroot\wss\VirtualDirectories\GUID\_app_bin)操作事件接收器程序集。
内容类型
Windows SharePoint Services 3.0 在数据存储中引入了内容类型的概念。简而言之,内容类型为使用 Windows SharePoint Services 的 Web 设计人员引入了可重用性概念。Web 设计人员现在能够创建具有特定定义和可能关联行为(例如类型名称、字段、格式、业务流程、保留、审计和事件处理)的对象类。您现在可以激活 SharePoint 列表和库以支持多种内容类型。当您这样做时,您可以将一个或多个这些类附加到您的列表或库,从而用附加功能和行为扩展它。可以想象用联系人内容类型扩展客户列表。联系人内容类型可以为客户列表提供一组新字段,例如联系人姓名、职能、电话等,以及新的行为。
您现在可以为特定的内容类型定义事件处理程序。例如,您可以定义内容类型“客户”,并在其行为中定义事件处理程序的元数据。
特点
您使用功能定义内容类型。当您使用功能定义内容类型时,您会创建两个 XML 文件,如下所示:
事件故障排除
编程事件可能会导致异常行为,具体取决于您实现事件处理程序的上下文。下表描述了您在编写代码时可能遇到的与特定上下文相关的事件行为。
背景 | 描述 |
文档库和内容类型 |
您在文档库中创建了一个特定内容类型的 .aspx 页面,该页面关联了 ItemAdding 和 ItemAdded 事件,但事件未触发。 在添加阶段只存在默认内容类型属性。指定内容类型的附加属性(字段)只在更新阶段添加。因此,最佳实践是避免在指定内容类型 ID 的情况下触发 Add 事件。相反,在添加阶段将内容类型设置为默认内容类型。内容类型随后可以在更新阶段更改。另一种方法是在列表级别注册事件。 |
文档库和内容类型 |
即使上传的文档不是该类型,绑定到内容类型的 ItemAdding 事件也会触发。 当您第一次将文档添加到库时,内容类型始终是与列表关联的默认内容类型。文档的内容类型可以在更新阶段更改,内容类型 ID 也将相应调整。 |
文档库和内容类型 |
通过列表表单删除项目的请求没有关联的内容类型 ID,但这会导致 ItemDeleting 或 ItemDeleted 事件在所有项目上触发,而不仅仅是特定内容类型的项目,即使事件只为该内容类型注册。 根据设计,当请求未绑定到内容类型时,Windows SharePoint Services 会为列表中的所有项目触发事件,以允许在事件接收器注册到列表中的所有项目时为所有项目触发事件。 此行为会影响涉及 Delete 事件的策略。如果您实施涉及删除的策略,将策略应用于内容类型,然后将内容类型绑定到列表,则该策略将应用于列表中的所有项目,而不仅仅是应用于该策略的内容类型的项目。 |
列表和内容类型 |
您在绑定到列表的内容类型上注册了 ItemUpdating 和 ItemUpdated 事件,但即使通过对象模型更新的不是该内容类型的项目,事件也会触发。 Windows SharePoint Services 返回 0(零)作为内容类型 ID,而不是项目的实际内容类型 ID。 |
列表 |
BeforeProperties 属性仅适用于 DocumentLibrary 类型的列表。 解决方法是使用对象模型和给定的列表项 ID 返回属性。 |
文档库 |
您向文档库添加了一个自定义内容类型。ItemAdding、ItemAdded 和 ItemUpdating 事件触发,但 ItemUpdated 事件不触发。 此行为仅发生在共享文档文档库,而不发生在自定义文档库。对于共享文档,添加内容类型会创建一个 Forms/<Content Type> 文件夹,并将 Template.doc 文件复制到该文件夹中,从而触发事件。 |
文档库和内容类型 |
对于文件夹,您可以通过 ItemAdding 和 ItemAdded 事件中的 AfterProperties 属性获取内容类型和内容类型 ID,但对于文档,您只能在 ItemAdded 事件中获取内容类型 ID,在 ItemAdding 事件中获取不到任何内容。 Microsoft Office system 文档的 Windows SharePoint Services 分析器未在文档字典中设置内容类型名称。文档元数据未设置内容类型名称。 |
列表 | 列表事件未在 UserInfo 列表上触发。 |
列表 | ItemAdded 事件在文件夹类型项目上触发,但未返回列表项 ID。 |
文档库 | 当文档副本与原始文档取消链接时,事件不会触发。 |
文档库 |
当事件在 Forms 文件夹中的文档上触发时,列表项 ID 始终等于 0。如果您在文档库中注册 ItemUpdating 事件,然后修改 EditForm.aspx,事件会触发,但 ID 等于 0(零),因为该项不是常规列表项。 |
列表 | 当列表通过 Onet.xml 预配,并且列表类型具有将接收器绑定到列表的关联功能时,事件接收器不会绑定到列表。您创建了一个将接收器绑定到列表类型的功能,通过站点定义创建了该类型的列表,但当站点预配时,接收器未绑定到列表。解决方法是改为将接收器绑定到内容类型,然后将内容类型绑定到列表。 |