SharePoint 事件接收器,纯代码

列表 BeforeProperties AfterProperties properties.ListItem
ItemAdding 没值 新值 空
ItemAdded 没值 新值 新值
ItemUpdating 没值 更改的值 老值
ItemUpdated 没值 更改的值 更改的值
ItemDeleting 没值 没值 老值
ItemDeleted 没值 没值 空

“没值”的意思是该栏的值在哈希表中不可用。

“新值”的意思是该栏当前的值是可用的。

“更改的值”的意思是该栏修改后的值是可用的。

“老值”的意思是该栏在修改前的值是可用的。

下面是对于文档库的测试结果:

文档库 BeforeProperties AfterProperties properties.ListItem
ItemAdding 没值 没值  空
ItemAdded 没值 没值 新值
ItemUpdating 老值 更改的值 老值
ItemUpdated 老值 更改的值 更改的值
ItemDeleting 没值 没值 老值
ItemDeleted 没值 没值 空

Properties.ListItem是指列表项在事件中当前的值。空表示该项不可用。通过我的分析得到如下结论:

毫不奇怪,我们在ItemAdding(在项被添加前)和ItemDeleted(在项被删除后)得到的是空值。之前Lshai Sagi也证明过这一点。

 
 
 
 
 
 
 

每个方法都有一个SPItemEventProperties参数,包含很多关于提交记录的相关信息。

具体信息请参考MSDN文档 http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spitemeventproperties_members.aspx

 

二、结构分析(以SPItemEventReceiver为例):

复制代码
namespace CustomEventReceiver.EventReceiver1

{

    /// <summary>

    /// 列表项事件

    /// </summary>

    public class EventReceiver1 : SPItemEventReceiver

    {

       /// <summary>

       /// 正在添加项.

       /// </summary>

       public override void ItemAdding(SPItemEventProperties properties)

       {

           base.ItemAdding(properties);

       }

    }

}
复制代码

生成的事件处理代码,继承自SPItemEventReceiver,重写ItemAdding(添加Item前的事件)代码。

复制代码
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Receivers ListTemplateId="100">

      <Receiver>

        <Name>EventReceiver1ItemAdding</Name>

        <Type>ItemAdding</Type>

        <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>

        <Class>CustomEventReceiver.EventReceiver1.EventReceiver1</Class>

        <SequenceNumber>10000</SequenceNumber>

      </Receiver>

  </Receivers>

</Elements>
复制代码

Receiver通常包含五个子节点:

1、Name:定义唯一名字信息;

2、Type:定义一个事件类型,如果添加新的事件类型,需要再添加一个Receiver子节点;

3、Assembly:定义sharepoint程序集清单;Sharepoint Assembly

4、Class:包含带命名空间的事件处理器类的类名;

5、SequenceNumber:如果有多个事件处理器绑定到同一个列表的时候通过此节点值判断执行顺序

 

如果希望值绑定在某个特定的列表,可以通过修改以下内容:

<Receivers ListUrl="Lists/列表名">

 

通过添加data标签,可以像事件处理器传递少量数据信息:

复制代码
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Receivers ListTemplateId="100">

      <Receiver>

        <Name>EventReceiver1ItemAdding</Name>

        <Type>ItemAdding</Type>

        <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>

        <Class>CustomEventReceiver.EventReceiver1.EventReceiver1</Class>

        <SequenceNumber>10000</SequenceNumber>

         <Data> Data information<Data>

      </Receiver>

  </Receivers>

</Elements>
复制代码

读取方法:

String  data=properties.ReceiverData;

 

三、事件绑定

方法一:Feature绑定

在Element.xml文件中定义内容,部署。

缺陷:通过XML配置,无法将内容类型和事件处理器进行绑定,而通过对象模型的方式可以。

 

方法二:用sharepoint对象模型进行绑定

参考代码:

复制代码
Type receiverType = typeof(事件查看器类);       //typeof取得系统对类的描述

            using (SPSite site = new SPSite("http://localhost/sites"))

            {

                SPWeb web = site.RootWeb;

                SPList list = web.Lists.TryGetList("列名");

                SPEventReceiverDefinitionCollection receiverCol = list.EventReceivers;

                SPEventReceiverDefinition recevierDef = receiverCol.Add();

                recevierDef.Assembly = receiverType.Assembly.FullName;

                recevierDef.Class = "CustomEventReceiver.EventReceiver1.EventReceiver1";

                recevierDef.Type = SPEventReceiverType.ItemAdding;

                recevierDef.SequenceNumber = 10000;                      

                recevierDef.Update();

            }
复制代码

在绑定前要做个判断,确保同一个事件处理器没有和相应的列表绑定,加入如下代码:

复制代码
SPEventReceiverDefinitionCollection receiverCol = list.EventReceivers;
foreach (SPEventReceiverDefinition def in receiverCol)
          {
              if (def.Assembly == receiverType.Assembly.FullName)
                {
                        def.Delete();
                        break;           
                }
            }
复制代码

 

四、其他应用

After事件:注册同步After事件的方法(默认为异步):

1、XML绑定

复制代码
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Receivers ListTemplateId="100">

      <Receiver>

        <Name>EventReceiver1ItemAdding</Name>

        <Type>ItemAdding</Type>

        <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>

        <Class>CustomEventReceiver.EventReceiver1.EventReceiver1</Class>

        <SequenceNumber>10000</SequenceNumber>

                  <Synchronization>Synchronous</Synchronization>

      </Receiver>

  </Receivers>

</Elements>
复制代码

2、SharePoint对象模型

复制代码
Type receiverType = typeof(事件查看器类);       //typeof取得系统对类的描述

            using (SPSite site = new SPSite("http://localhost/sites"))

            {

                SPWeb web = site.RootWeb;

                SPList list = web.Lists.TryGetList("列名");

                SPEventReceiverDefinitionCollection receiverCol = list.EventReceivers;

                                   foreach (SPEventReceiverDefinition def in receiverCol)

                {

                    if (def.Assembly == receiverType.Assembly.FullName)

                    {

                        def.Delete();

                        break;                //删除后需要加上break,否则foreach会在删除后报错

                    }

                }

                SPEventReceiverDefinition recevierDef = receiverCol.Add();

                recevierDef.Assembly = receiverType.Assembly.FullName;

                recevierDef.Class = "CustomEventReceiver.EventReceiver1.EventReceiver1";

                recevierDef.Type = SPEventReceiverType.ItemAdding;

                recevierDef.SequenceNumber = 10000;                    

                                  recevierDef.Synchronization=SPEventReceiverSynchronization.Synchronous;

                recevierDef.Update();

            }

 
复制代码

避免二次触发引起的无限循环调用(如调用Update方法修改数据后继续调用Update方法,一直到资源超限),使用EventFiringEnabled属性:

复制代码
public override void ItemUpdated(SPItemEventProperties properties)

       {

           this.EventFiringEnabled = false;

           properties.ListItem["Title"] = "Title";

           properties.ListItem.Update();

           this.EventFiringEnabled = true;

       }
复制代码

如果在更新有版本控制的列表项时不希望更新版本,则调用SPListItem的另一个Update方法:

properties.ListItem.UpdateOverwriteVersion();

 

SPListItem还有另外一种更新方式SystemUpdate(),可以再更新数据时不触发其他关联字段。

MSDN解释:

Updates the database with changes that are made to the list item without changing the Modified or Modified By fields.

SystemUpdate方法有两个重载,带有bool参数的重载可以指定是否生成新的版本。

复制代码
       public override void ItemUpdated(SPItemEventProperties properties)

       {

           this.EventFiringEnabled = false;

           properties.ListItem["Title"] = "Title";

           properties.ListItem.SystemUpdate();

           this.EventFiringEnabled = true;   

       }
复制代码

posted on 2015-05-20 21:34  !无名之辈  阅读(319)  评论(0)    收藏  举报