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);
}

Inserting a link from SharePoint to a Word document (or other item) fails

Recently, my client reported that a user, while editing a news article, was unable to insert a link to a Word document from SharePoint. They used the ribbon like so:

They sent me a screenshot of the resulting “Select an asset” picker. The user had selected a Word document, but the document’s URL had not been populated in the Location (URL) field. Therefore, clicking OK returned a (rather obscure, user-unfriendly) error message along the lines of “Cannot redirect to an invalid URL – the protocol is missing or invalid” (loosely translated from the Danish language pack). The error essentially means, “You can’t submit an empty URL field”.

Why wasn’t the URL being populated? By sheer luck I discovered that the nature of the view in the dialog had an impact on whether the documents were selectable or not.

You need the “Type” column on the view in order for the item to be selectable. This folder, for instance, has such a column, so its contents are selectable. If there’s no “Type” column, the URL may not be populated in the “Location (URL)” field upon selecting an item.

I hope this saves you all some time of scratching your heads.