Wednesday, March 17, 2010

ErrorWebPart instead of SummaryLinkWebPart

I was working with some custom development where I needed to import some webpart from a top level page. This was done in 2 stages:

  1. it would start as the execution of a user button's action, i.e. the user would have a page to explicitly execute some code, including the webpart import.
  2. some event handlers would also trigger this same action, i.e. whenever someone checked in a pre-determined page.
In the first case, everything went fine. The webparts were successfully imported.

In the second case, the SummaryLinkWebPart would not be imported. Actually, the SPLimitedWebPartManager would not return a SummaryLinkWebPart, but a ErrorWebPart. It was a customized SummaryLinkWebPart, with a non-default MainXslLink, ItemXslLink and so on...

Apparently, the SPLimitedWebPartManager (or the SummaryLinkWebPart) need to have a request/context set in order to create/return the correct WebPart. Since in an Event Handler (or Timer Job) those objects are not created by default, it would return you that error object.

To make things worse, my code would return a "No parameterless constructor" exception on that ErrorWebPart, which got me in the wrong way to start with.

How to solve it? Just create the necessary objects, before getting the webparts from the SPLimitedWebPartManager:

HttpRequest request = new HttpRequest("", destinationWeb.Url, "");
HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter()));
HttpContext.Current.Items["HttpHandlerSPWeb"] = destinationWeb;

where destinationWeb is the web where the page you are importing webparts to is located (and perhaps it can actually be any web).

Don't know what really happens inside the Microsoft code to cause this behaviour, but I'm guessing it is some use of SPContext.Current to get a SharePoint object (like CurrentWeb).

No comments:

Post a Comment