I am trying to programmatically create a Calendar List in SharePoint 2010 whenever a particular list is created using a Sandbox Solution. I have implemented a ListAdded ListEventReceiver in order to run the code to generate the calendar.
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();
}
}
When I call spWeb.Lists.Add(...), I get an SPException (The sandboxed code execution requested was refused because the Sandboxed Code Host Service was too busy to handle the request.)
From the MSDN documentation, I can see that that the SPListCollection.Add method is available in Sandboxed Solutions (https://msdn.microsoft.com/en-us/library/office/ms413986(v=office.14).aspx). Is there a restriction against creating a list in this event receiver like this? Does anyone know why this doesn't work?
Edited to add the generated Feature.xml and Elements.xml files
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>
I found the answer. Apparently creating a list within this event receiver was causing a recursive call to the event receiver, even though I had a check in place to exit out on non-MyList template-based lists. The solution was to simply add 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
...