在 ListAdded 列表事件接收器中创建列表

Creating a list in ListAdded List Event Receiver

每当使用沙盒解决方案创建特定列表时,我都会尝试以编程方式在 SharePoint 2010 中创建日历列表​​。我已经实现了一个 ListAdded ListEventReceiver 以便 运行 生成日历的代码。

public class GenerateCalendar : SPListEventReceiver
{
   public override void ListAdded(SPListEventProperties properties)
   {
      base.ListAdded(properties);

      // Exit out if this is not a MyList type
      if(!IsMyList(properties))
         return;

      string calendarTitle = properties.List.Title + " Calendar";

      SPWeb spWeb = properties.Web;
      SPListTemplateType type = new SPListTemplateType();
      type = SPListTemplateType.Events;

      // Execution breaks here:
      Guid listGuid = spWeb.Lists.Add(calendarTitle, "Associated Calendar", type);
      SPList newList = spWeb.Lists[listGuid];
      newList.OnQuickLaunch = properties.List.OnQuickLaunch;
      newList.Update();
   }
}

当我调用 spWeb.Lists.Add(...) 时,我得到一个 SPException(请求的沙盒代码执行被拒绝,因为沙盒代码主机服务太忙来处理请求。)

从 MSDN 文档中,我可以看到 SPListCollection.Add 方法 在沙盒解决方案 (https://msdn.microsoft.com/en-us/library/office/ms413986(v=office.14).aspx) 中可用 。像这样在这个事件接收器中创建列表有限制吗?有谁知道为什么这不起作用?

编辑以添加生成的 Feature.xml 和 Elements.xml 文件

Feature.xml:

<?xml version="1.0" encoding="utf-8"?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
   Title="Calendar Generator"
   Description="Generates a calendar"
   Id="dfe3388c-c063-4873-a41b-5c066907c510"
   Scope="Web">
   <ElementManifests>
      <ElementManifest Location="GenerateCalendar\Elements.xml" />
   </ElementManifests>
</Feature>

Elements.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   <Receivers >
      <Receiver>
         <Name>GenerateCalendarListAdding</Name>
         <Type>ListAdding</Type>
         <Assembly>MyListGenerator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5cff2198a602ec41</Assembly>
         <Class>MyListGenerator.Event_Receivers.GenerateCalendar.GenerateCalendar</Class>
         <SequenceNumber>10000</SequenceNumber>
      </Receiver>
      <Receiver>
         <Name>GenerateCalendarListDeleting</Name>
         <Assembly>MyListGenerator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5cff2198a602ec41</Assembly>
         <Class>MyListGenerator.Event_Receivers.GenerateCalendar.GenerateCalendar</Class>
         <SequenceNumber>10000</SequenceNumber>
      </Receiver>
      <Receiver>
         <Name>GenerateCalendarListAdded</Name>
         <Type>ListAdded</Type>
         <Assembly>MyListGenerator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5cff2198a602ec41</Assembly>
         <Class>MyListGenerator.Event_Receivers.GenerateCalendar.GenerateCalendar</Class>
         <SequenceNumber>10000</SequenceNumber>
      </Receiver>
   </Receivers>
</Elements>

您可以在沙盒解决方案中创建派生自 SPListEventReceiver 的事件接收器。但是,事件接收器必须在您的功能元素文件中注册 declaratively;它不能使用对象模型注册(例如通过功能接收器)。

很可能您 运行 限制了允许您的沙盒解决方案使用的 资源点 数量,尽管您也可能 运行 进入每个请求可以消耗的资源的绝对限制。

此外,如果您的环境运行速度特别慢,如果在单个请求期间超过其时间限制(默认为 30 秒),用户代码服务将被回收。

有关详细信息,请参阅 Microsoft 沙盒解决方案 文档的“了解解决方案监控”部分:https://msdn.microsoft.com/en-us/library/ff798382.aspx

相关摘录如下。

资源点:

If the solutions in a site collection exceed the daily resource point allocation for that site collection, SharePoint will take every sandboxed solution in the site collection offline for the rest of the day.

Resource points are calculated according to 14 different measurements known as resource measures, including CPU execution time, memory consumption, and unhandled exceptions.

...

SharePoint counts the most expensive resource measure toward the total for the solution, instead of the sum of all measures.

绝对限制:

To prevent rogue sandboxed solutions from causing instability SharePoint also monitors individual sandboxed solutions per request. Each of the 14 resource measures includes an AbsoluteLimit property that defines a hard limit of the resources that a sandboxed solution can consume in a single request. If an absolute limit is exceeded, SharePoint terminates the request by stopping and restarting the Sandbox worker process. For example, the CPU execution time resource measure has a default absolute limit of 60 seconds. If a single request takes more than 60 seconds to execute, the user code service will stop and restart the sandbox worker process that is executing the request.

WorkerProcessExecutionTimeout:

In addition, the user code service includes a property named WorkerProcessExecutionTimeout with a default value of 30 seconds. If this time limit is exceeded during a single request, the user code service will recycle the application domain in question and the request will return an error.

我找到了答案。显然,在此事件接收器中创建一个列表会导致对事件接收器的递归调用,即使我有一个检查以退出非 MyList 基于模板的列表。解决方案是简单地添加 EventFiringEnabled = false.

...
SPWeb spWeb = properties.Web;
SPListTemplateType type = new SPListTemplateType();
type = SPListTemplateType.Events;

EventFiringEnabled = false;  // Disable event firing and create the list
Guid listGuid = spWeb.Lists.Add(calendarTitle, "Associated Calendar", type);
SPList newList = spWeb.Lists[listGuid];
newList.OnQuickLaunch = properties.List.OnQuickLaunch;
newList.Update();
EventFiringEnabled = true;  // Re-enable event firing
...