如何为特定模板ID的列表添加事件接收器

7
我正在为自定义列表模板添加ItemAdding事件接收器。事件接收器和列表模板都由同一特征部署。同一特征还创建了列表实例。
我的问题是,该事件在部署到的站点中的每个列表项上都会触发。Eventreceiver的Elements.xml如下:
<Receivers ListTemplateId="10200">
  <Receiver>
    <Name>ListEventReceiverItemAdding</Name>
    <Type>ItemAdding</Type>
    <Assembly>$SharePoint.Project.AssemblyFullName$</Assembly>
    <Class>SharepoitProject.ListEventReceiver</Class>
    <SequenceNumber>10000</SequenceNumber>
  </Receiver>
</Receivers>

我不确定我做错了什么,我已经从这里做了几乎所有的事情。

环境:此网站上的Sharepoint 2010与发布功能。


你的意思是每个列表项都会触发它,对于每个列表都是这样吗? - Ashish Patel
我的意思是,当网站上的某个列表(不一定是从模板10200创建的列表)添加了某个项目时,就会触发该事件。 - Lukasz S
听起来有点奇怪,但你做得很对。尝试在全新的网站集合上激活该功能,以确保它在开发期间没有附加到所有列表上。 - Ashish Patel
是的,我已经尝试过了,没有任何变化。 - Lukasz S
是的,我已经尝试过使用GUID(没有变化)。我已经检查了列表实例EventReceivers - 它是空的(在ItemAdding方法中进行了检查)。 - Lukasz S
显示剩余2条评论
4个回答

13

我的事件接收器也遇到了同样的问题。我尝试使用ListTemplateId、ListTemplateOwner,甚至是ListUrl。我知道这些设置是有效的,但它们被忽略了,该接收器会附加到每个列表。

我有一种预感,可能与事件接收器在站点范围功能内声明有关。这似乎得到了 SPEventElement 的“文档”证实

  switch (this.FeatureDefinition.Scope)
  {
    case SPFeatureScope.Site:
      if (this.SiteScopedReceivers())
      {
        this.UpdateEventReceiversForSite(site, sqlcmdAppendOnly, new SPEventElement.GetSqlToUpdateEventReceiversForSite(this.GetEventReceivers(site.RootWeb).GetSqlToAddEventReceiversToSite));
        break;
      }
      else
      {
        this.UpdateEventReceiversForWeb(site.RootWeb, sqlcmdAppendOnly, new SPEventElement.GetSqlToUpdateEventReceiversForWeb(this.GetEventReceivers(site.RootWeb).GetSqlToAddEventReceiversToWeb));
        break;
      }
    case SPFeatureScope.Web:
      if (this.RootWebOnly && !web.IsRootWeb)
      {
        ULS.SendTraceTag(1718513714U, (ULSCatBase) ULSCat.msoulscat_WSS_General, ULSTraceLevel.Verbose, "Event Receivers in Feature '{0}' were not activated because current web is not the root web.", new object[1]
        {
          (object) this.FeatureDefinition.Id.ToString("B")
        });
        break;
      }
      else
      {
        bool templateIdExists;
        int templateId;
        this.CheckTemplateId(out templateIdExists, out templateId);
        if (!templateIdExists)
        {
          if (this.ListUrl != null)
          {
            this.UpdateEventReceiversForList(web, sqlcmdAppendOnly, new SPEventElement.GetSqlToUpdateEventReceiversForList(this.GetEventReceivers(web).GetSqlToAddEventReceiversToList), true);
            break;
          }
          else
          {
            this.UpdateEventReceiversForWeb(web, sqlcmdAppendOnly, new SPEventElement.GetSqlToUpdateEventReceiversForWeb(this.GetEventReceivers(web).GetSqlToAddEventReceiversToWeb));
            break;
          }
        }
        else
        {
          if (this.ListUrl != null)
            throw new SPException(SPResource.GetString("ElementHasBothTemplateIdAndUrl", new object[0]));
          this.UpdateEventReceiversForListTemplate(templateId, web, sqlcmdAppendOnly, new SPEventElement.GetSqlToUpdateEventReceiversForList(this.GetEventReceivers(web).GetSqlToAddEventReceiversToList));
          break;
        }
      }
  }

看起来ListTemplateId、ListTemplateOwner和ListUrl在站点范围的功能中被忽略了。当我将我的事件接收器元素移到Web范围的功能中时,该接收器仅正确附加到所需的列表。


Web范围事件接收器。不错! - Dennis G

3

当作用于网站时,它将对所有列表触发。当我将解决方案作用于网页时,它能够正常工作。希望这有所帮助。


2

来自MSDN SDK - http://msdn.microsoft.com/en-us/library/ms431081.aspx


Receivers标记可以意味着站点范围的事件注册或根Web的事件注册。Scope属性用于定义应用事件接收器的级别。如果Receivers标记没有ListTemplateId或ListUrl属性,则事件接收器将在与功能相同的范围内注册。例如,对Web进行作用域的功能会导致向作用域为Web的事件接收器集合添加事件接收器。


这让我认为您提供的列表模板ID可能无效。


1

如果你需要为特定的列表配置事件接收器,你必须设置这个属性,那么它将会有效。

但是请确保你的功能具有 Web 范围而不是站点范围,因为如果是站点范围,它将会在系统中的所有列表上触发。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接