I’ve been working with the Content Query Web Part in SharePoint 2010 and battling for a couple of days now with a bug when using the PageQueryString filter introduced in SP2010. From what I can work out, this bug is apparent when trying to use the PageQueryString filter and restricting the query to a specific content type. My colleague Martin Hatch has also run into what looks like the same problem.
As it was so frustrating, and I didn’t want to have to ask my guys to go straight to custom code to fix it, I spent some time trying to track down what was causing the bug. My results are below, however if you’re interested in simply finding a workaround to this bug then scroll to the bottom of the post.
First I needed to identify exactly when/ where the bug was occurring. There were three main areas of the query that I felt needed to be tested:
- Source, i.e. query whole site or specific list
- Content Type, i.e. query all types or a specific type
- PageQueryString filter, i.e. restricting the results by querystring
Putting these together gave me 12 permutations of configured web parts to look into. Fast forward a boring hour or so of testing and the results are below:
|Source||Content Type||PageQueryString Filter||Without QueryString||With QueryString|
By ‘Success’ I mean that the result was as expected. ‘Failure’ meant that the results weren’t as expected – often meaning no results.
In the last scenario the CQWP actually gave me an error message indicating that the query was badly formed, yet to make it work all I needed to do was add in a querystring and it started returning results (and the right ones too). [The expected behaviour is that if no querystring is provided then it should not be included in the query.]
How to get to the bottom of this? Step forward the excellent ULS Viewer. With this I was able to see the CAML query that was being generated as the page was rendered. Here is the CAML for the scenario 4 above, querying on a specific content type and using the PageQueryString filter.
First with a querystring provided:
Now without a querystring provided:
Looking at the two you can see that the CAML query formed when a querystring is not provided is incorrect as there is an <And> operator with only one argument. Frustrating.
So now for the workaround. If the CAML query is poorly formed around the <And> operator then I think we need to ensure that the operator always has at least two values, regardless of if the querystring is provided or not. In effect we are adding an additional filter which always resolves to True.
For my situation, I knew that the Title field would always have a value and so I was able to add a ‘Title not equal to null’ filter (null set by not adding a value). Looking at the CAML query again you can see that the query is now correctly formed, and more importantly the expected results are returned!