- November
- 26
- 2007
Error in ContentByQueryWebPart when calling from a non-web context
Posted by koning53
No Comments »
Just run in some strange behaviour of the Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart, better known as the Content Query Webpart.
I want to update a large number of these webparts, so I've made the following console app doing the work for me:
foreach (SPFile file in [spweb].Files) { using (SPLimitedWebPartManager wpMan = file.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared)) { SPLimitedWebPartCollection wpColl = wpMan.WebParts; int numberOfWebparts = wpColl.Count; for (int i = 0; i < numberOfWebparts; i++) { System.Web.UI.WebControls.WebParts.WebPart wp = (System.Web.UI.WebControls.WebParts.WebPart)wpColl; if (wp is Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart) { ((ContentByQueryWebPart)wp).ListGuid = [spweb].Lists[((ContentByQueryWebPart)wp).ListName].ID.ToString(); ((ContentByQueryWebPart)wp).WebUrl = [spweb].ServerRelativeUrl; wpMan.SaveChanges(wp); } wp.Dispose(); } wpMan.Web.Dispose(); // dispose manual because of a memoryleak in SPWebpartManager (http://blog.ofonesandzeros.com/2007/06/05/splimitedwebpartmanager-memory-leak) } }
This code loops through all webparts on all pages, checks to see if the webpart is a ContentByQueryWebpart and updates some properties. This works, as long as you don't change the HeaderXslLink, ItemXslLink or MainXslLink in properties the .webpart file!
As soon as you change one of those the webpartmanager will retrun a Microsoft.SharePoint.WebPartPages.ErrorWebPart. Why? Because of the following code is called by the specific properties of the ContentByQueryWebpart (actually its parent, the CmsDataFormWebpart):
internal static string MakeServerRelativeUrl(string url) { return concatenateUrls(SPContext.GetContext(HttpContext.Current).Site.ServerRelativeUrl, url); }
The webpart will always call the SPContext, but from a console application there is no web-context. Therefore when initiating the ContentByQueryWebpart, it will always thow an exception like:
"An error occured while setting the value of this property: Microsoft.SharePoint.Publishing.WebControls.ContentByQueryWebPart:MainXslLink – Exception has been thrown by the target of an invocation."
This can be seen as a design error, since all webparts should be able to at least expose themselves through a WebpartManager. Once the real rendering is done calls to the SPContext can be made.