0

我正在尝试在 SharePoint 中注册一个 WebDeleting 事件接收器。这在我的开发环境中运行良好,但在几个暂存环境中却不行。我得到的错误是“值不在预期范围内。”。这是我使用的代码:

SPSecurity.RunWithElevatedPrivileges(delegate()
{
    using (SPSite elevatedSite = new SPSite(web.Site.ID))
    {
        using (SPWeb elevatedWeb = elevatedSite.OpenWeb(web.ID))
        {
            try
            {
                elevatedWeb.AllowUnsafeUpdates = true;
                SPEventReceiverDefinition eventReceiver = elevatedWeb.EventReceivers.Add(new Guid(MyEventReciverId));
                eventReceiver.Type = SPEventReceiverType.WebDeleting;
                Type eventReceiverType = typeof(MyEventHandler);
                eventReceiver.Assembly = eventReceiverType.Assembly.FullName;
                eventReceiver.Class = eventReceiverType.FullName;
                eventReceiver.Update();
                elevatedWeb.AllowUnsafeUpdates = false;
            }
            catch (Exception ex)
            {
                // Do stuff...
            }
        }
    }
});

我意识到我可以通过一个特征元素文件来做到这一点(我现在正在尝试这种方法),但更喜欢使用上述方法。

我在 ULS 日志中一直得到的错误是:

03/11/2010 17:16:57.34  w3wp.exe (0x09FC)                           0x0A88  Windows SharePoint Services     Database                        6f8g    Unexpected  Unexpected query execution failure, error code 3621. Additional error information from SQL Server is included below. "The statement has been terminated." Query text (if available): "{?=call proc_InsertEventReceiver(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}"  
03/11/2010 17:16:57.34  w3wp.exe (0x09FC)                           0x0A88  Windows SharePoint Services     General                         8e2s    Medium      Unknown SPRequest error occurred. More information: 0x80070057   

有任何想法吗?


更新 - 我学到了一些有趣的东西......

我修改了我的代码以执行以下操作:

  • 我在没有 GUID 的情况下调用 EventReceivers.Add() 因为我看到的大多数示例都没有这样做
  • 给事件接收者一个名称和序列号,因为我看到的大多数例子都是这样做的

我将此更改与一些额外的跟踪语句一起部署到 ULS 日志中,并且在执行了足够的 iisreset 并清除了我的程序集的 GAC 之后,我开始在 ULS 日志中看到我的新跟踪语句并且我不再收到错误!

所以,我开始回到我原来的代码,看看究竟是什么改变有帮助。我终于在源代码控制中使用了原始版本,它仍然有效:-S。

所以答案很明显是一些缓存问题。但是,当我最初试图让它工作时,我尝试了 IISRESET,重新启动了一些 SharePoint 服务 OWSTimer(我相信这会运行事件处理程序,但可能不涉及我收到错误的事件注册),并且甚至重新启动以确保没有程序集缓存正在进行 - 而这在以前没有帮助。

我唯一要做的就是遵循以下步骤:

  1. 清除包含注册码和事件处理程序类的程序集的 GAC。
  2. 做一个IISRESET。
  3. 卸载 WSP。
  4. 做一个IISRESET。
  5. 安装 WSP。
  6. 做一个IISRESET。

为了让它工作,我从来没有重新启动或重新启动 SharePoint 服务,但我在让它工作之前(在更改我的代码之前)完成了这些工作。

我想我可以用 Reflector 进行更多挖掘,看看我能找到什么,但我相信你很快就会走到死胡同(非托管代码)。我想知道什么可以保留旧的 DLL?我无法想象 SQL Server 会以某种方式出现。即便如此,重新启动也会解决这个问题(整个场,包括 SQL Server 在此环境中位于同一台计算机上)。

4

1 回答 1

0

因此,似乎整个问题是通过提供 GUID 创建事件接收器。

EventReceiverDefinition eventReceiver = elevatedWeb.EventReceivers.Add(new Guid(MyEventReciverId));

现在我在做:

EventReceiverDefinition eventReceiver = elevatedWeb.EventReceivers.Add();

不幸的是,这意味着当我想知道事件是否已经注册时,我必须执行类似于下面的代码的操作,而不是单行。

// Had to use the below instead of: web.EventReceivers[new Guid(MyEventReceiverId)]
private SPEventReceiverDefinition GetWebDeletingEventReceiver(SPWeb web)
{
    Type eventReceiverType = typeof(MyEventHandler);
    string eventReceiverAssembly = eventReceiverType.Assembly.FullName;
    string eventReceiverClass = eventReceiverType.FullName;

    SPEventReceiverDefinition eventReceiver = null;

    foreach (SPEventReceiverDefinition eventReceiverIter in web.EventReceivers)
    {
        if (eventReceiverIter.Type == SPEventReceiverType.WebDeleting)
        {
            if (eventReceiverIter.Assembly == eventReceiverAssembly && eventReceiverIter.Class == eventReceiverClass)
            {
                eventReceiver = eventReceiverIter;
                break;
            }
        }
    }

    return eventReceiver;
}

目前尚不清楚为什么事情似乎会徘徊并需要进行一些清理(iisreset、重新启动等),所以如果其他人有这个问题,请记住这一点。

于 2010-03-17T13:55:56.013 回答