Exception when trying to access a list on a different website during ItemDeleting event

In a SharePoint 2010 sandboxed solution, I was trying to accomplish the following in a SharePoint ItemDeleting event:
– Read a field value from the item being deleted
– Based on this value, delete a corresponding list item in a list on another website.

This gave me quite a headache. I was able to read the value on the source list:

public override void ItemDeleting(SPItemEventProperties properties)
{
  var value = properties.ListItem["sourceField"];
  base.ItemDeleting(properties);
}

I was also able to open the root web and get the target list that I’m deleting from:

public override void ItemDeleting(SPItemEventProperties properties)
{
  SPList projectInfoAllList = Utility.GetAiProjectInfoAllList(properties.Web);
  base.ItemDeleting(properties);
}

//Snippet from Utility class
public static SPList GetAiProjectInfoAllList(SPWeb currentWeb)
{
  string rootWebUrl = currentWeb.Site.RootWeb.Url;
  string projectInfoAllListRelativeUrl = new ConfigurationManager(currentWeb).AiSiteProjectInfoAllListRelativeUrl;
  return currentWeb.GetList(rootWebUrl + projectInfoAllListRelativeUrl);
}

However, I couldn’t do both things without encountering an exception. That is, I could either read the ListItem[“sourceField”] value or open the target list, but not both. When I did, I got:

—————
A first chance exception of type ‘Microsoft.SharePoint.SPException’ occurred in mscorlib.dll

InnerException:¬†{“<nativehr>0x80070001</nativehr><nativestack></nativestack>”}

NativeErrorMessagse: FAILED hr detected (hr = 0x80070001)
Server stack trace:
at Microsoft.SharePoint.SPGlobal.HandleComException(COMException comEx)
at Microsoft.SharePoint.Library.SPRequest.GetMetadataForUrl(String bstrUrl, Int32 METADATAFLAGS, Guid& pgListId, Int32& plItemId, Int32& plType, Object& pvarFileOrFolder)
at Microsoft.SharePoint.SPWeb.GetList(String strUrl)
at Microsoft.SharePoint.SPWeb_SubsetProxy.GetList__Inner(String strUrl)
at Microsoft.SharePoint.SPWeb_SubsetProxy.GetList(String strUrl)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)

Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Microsoft.SharePoint.SPWeb_SubsetProxy.GetList(String strUrl)
at Microsoft.SharePoint.SPWeb.GetList__Inner(String strUrl)
at Microsoft.SharePoint.SPWeb.GetList(String strUrl)
at PPMTool.Common.Utility.GetAiProjectInfoAllList(SPWeb currentWeb)
—————

This exception doesn’t give you many hints, but the problem turned out, perhaps not surprisingly, to be related to the context I was in. For one reason or another, SharePoint doesn’t like that you manipulate a list on another site while in an ItemDeleting context. The way around this problem was to fire up a new SPWeb in a using statement, pulling the root web URL from the SPItemEventProperties object to get to keep things dynamic:

public override void ItemDeleting(SPItemEventProperties properties)
{
  //Get value from source list
  var value = properties.ListItem[&amp;quot;sourceField&amp;quot;];

  //Now get the list on the other site in a manner that doesn't fail:
  using (SPSite site = new SPSite(properties.WebUrl))
  {
   string rootWebUrl = properties.Web.Site.RootWeb.Url;
   using (SPWeb web = site.OpenWeb(rootWebUrl))
   {
   SPList projectInfoAllList = Utility.GetAiProjectInfoAllList(web);
   //Perform logic on projectInfoAllList based on the value we aquired above
   }
  }

  base.ItemDeleting(properties);
}
Advertisements