Thursday 11 April 2013

SharePoint Issue: Exception has been thrown by the target of an invocation while adding a CQWP

Summary Info:
SharePoint Version: 2010 Standard
OS:Windows 2008 R2

So, Yesterday I had another fantastically inexplicable issue.

I have this solution, this solution deploys a site definition, when the site is created, it activates a custom feature that processes the more complex requirements of the site, including some CQWP's whereby you been to set the listguid and weburl properties.

This solution was build and on both Dev and UAT it worked like a dream, but then it came to the production deployment, solution deployed, features activated, everything was looking rosey, until I tested creating a site, then boom "an unexpected error has occurred for correlation id.....", so there was me thinking there is an issue with the deployment that got glazed over, I checked the ULS logs for the correlation and there I found:

 Error Message   Exception has been thrown by the target of an invocation.   
  Error Stacktrace:  at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)  
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)  
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)  
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)  
   at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)  
   at Microsoft.SharePoint.WebPartPages.SPPropertyInfoPropertyEntry.SetValue(Object control, Object value)  
   at Microsoft.SharePoint.WebPartPages.BinaryWebPartSerializer.ExtractLinks(Object property, Object value, Int32 propertyLocation)  
   at Microsoft.SharePoint.WebPartPages.BinaryWebPartSerializer.Serialize(PersonalizationScope scope)  
   at Microsoft.SharePoint.WebPartPages.BinaryWebPartSerializer.get_Links()  
   at Microsoft.SharePoint.WebPartPages.SPWebPartManager.AddWebPartToStore(WebPart webPart, Int32 viewId, String viewGuid)  
   at Microsoft.SharePoint.WebPartPages.SPWebPartManager.AddWebPartInternal(SPSupersetWebPart superset, Boolean throwIfLocked)  
   at Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager.AddWebPartInternal(WebPart webPart, String zoneId, Int32 zoneIndex, Boolean throwIfLocked)  
   at Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager.AddWebPart(WebPart webPart, String zoneId, Int32 zoneIndex)  
   at {Logic Namespace}.AddCQWebPart(SPWeb rootWeb, SPLimitedWebPartManager webPartManager, String webpartName, String zoneId, Int32 zoneIndex, Guid listId, String url)  

What! what the hell is that!, the content query web part couldn't be added, OK!,  well that could be one of many issues:

  • SharePoint feature corruption
  • CQWP I'm referencing isn't there
  • Namespace is invalid
  • Couldn't set the properties

So I checked the webpart in the gallery, it looked ok, I added a webpart to the page through the UI, configured it to look at the list and it worked! so the .webpart is fine, the namespace and features are fine, so it looks like the property setting.

I removed the code setting the properties and still the error occurred  so as a process of deduction i took property after property out of the webpart until i found the properties breaking it, after taking the MainXsl, HeaderXsl and ItemXsl properties out of the .webpart file, the web parts deployed, why? good question!

So the SC I was deploying to was root and at "/" of the webapp so it cant be the URL of the properties.

Just to make sure I programatically set the urls of the xsl to the correct urls, when I did this I got another error!

 Error Message   Object reference not set to an instance of an object.   
  Error Stacktrace:  at Microsoft.SharePoint.Publishing.WebControls.CmsDataFormWebPart.MakeSiteRelativeUrl(String xslServerRelativeUrl)  
   at Microsoft.SharePoint.Publishing.WebControls.CmsDataFormWebPart.SetXSLLink()  
   at {Logic Namespace}.AddCQWebPart(SPWeb rootWeb, SPLimitedWebPartManager webPartManager, String webpartName, String zoneId, Int32 zoneIndex, Guid listId, String Url, String& errorMessage)  
   at {Logic Namespace}.AddCQPageWebPart(String pageUrl, String webPartName, String webPartZone, String listName)  

Ok now we're getting further down the rabbit hole!

Then I started investigating the context properties programmatically and found that when deploying this the HttpContext was null. I know this has been known to mess up some context sensitive operations. so I added the following before I attempted to instantiate the webpart to add:

 if (HttpContext.Current == null)  
 {  
      HttpRequest request = new HttpRequest("", rootWeb.Url, "");  
      HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter()));  
      HttpContext.Current.Items["HttpHandlerSPWeb"] = rootWeb;  
 }  

and viola! the web part started to deploy!

So in conclusion, the CQWP is very context sensitive, and to do anything programatically, make sure you have access to a HttpContext

No comments:

Post a Comment