views:

2385

answers:

4

I'm trying to write a CAML query that executes against a specific SPList, scoped to a specific folder, recursive from that point, and returns all ListItems (which meet a criteria) and Folders.

Here's the code for the query which seems like it should work (formatted for readability):

SPQuery query = new SPQuery();
query.Query = "
<Where>
    <Or>
        <Contains>
            <FieldRef Name=\"FileRef\" />
            <Value Type=\"Text\">foo</Value>
        </Contains>
        <Eq>
            <FieldRef Name=\"FSObjType\" />
            <Value Type=\"Lookup\">1</Value>
        </Eq>
    </Or>
</Where>";

query.ViewFields = "
<FieldRef Name=\"CustomField1\" Nullable=\"TRUE\" />
<FieldRef Name=\"CustomField2\" Nullable=\"TRUE\" />
<FieldRef Name=\"CustomField3\" Nullable=\"TRUE\" />
";

query.RowLimit = 500;
query.ViewAttributes = "Scope=\"RecursiveAll\"";
query.Folder = startingFolder;
DataTable dt = myList.GetItems(query).GetDataTable();

So - this only returns the ListItems - no folders.

If I remove the other conditions from the query, only leaving the FSObjType=1, I get a COM exception "Cannot complete this action. Please try again."

If I then remove the ViewFields, leaving only the Scope=RecursiveAll and FSObjType=1, I get an empty result set back.

A: 

I don't have my dev image to test against, so I might need to revise this later; but I think you could try

query.ViewAttributes = "Scope=\"Recursive\"";

Retrieving the items will allow you to use SPUtility.GetUrlDirectory(url) to get the folder path for a given item, and parse the folder hierarchy from there.

Gurdas Nijor
"Recursive" searches folders deeply but does not include folder objects in the result set. I would like to get all the information I need in one round trip - making dozens of API calls on top of the query is less than ideal.
Rex M
If I may ask, are you using this as a provider for some UI element such as a tree view that can use lazy loading? Or will you need to pull everything on a single pass?
Gurdas Nijor
@Gurdas everything needs to be fetched at once
Rex M
A: 

If I remove the other conditions from the query, only leaving the FSObjType=1, I get a COM exception "Cannot complete this action. Please try again."

Did you remove the <Or> tags when you did this? If not it will not run correctly.

Regardless, that does not solve your problem. Have you tried leaving the query empty? Does it return anything?

I have been working on something similar and ran into an issue as well, perhaps it's somewhat related.

Mark
Yes, all of my CAML queries are generated programmatically to avoid syntax errors such as a superfluous `<Or>`. This is not a syntax problem.
Rex M
Do you get a result set if you leave the query empty?
Mark
Sorry for the late response. I get a result set of items only if I remove all conditions.
Rex M
So you get all items in the specified folder? Also, have you tried adding the 'FileRef' and 'FSObjType' fields to the view section? WSS is poorly documented and quite inconsistent. Oh and make sure the view you are running this on has the folder option set.
Mark
A: 

You could try basing your caml query on the Folder Content Type instead,

<FieldRef Name='ContentType' /><Value Type='Text'>Folder</Value>

whilst keeping the

Query.ViewAttributes = "Scope=\"RecursiveAll\"";
Gavin Morgan
I've tried that, with the same results.
Rex M
+1  A: 

I've solved this putting:

<QueryOptions>
<IncludeAttachmentUrls>True</IncludeAttachmentUrls>
<Folder/> </QueryOptions>

As query option

I found my question about it on stack overflow:

http://stackoverflow.com/questions/173784/how-can-i-iterate-recursivly-though-a-sharepoint-list-using-webservices

volothamp
Interesting... I'll give this a try. What is the empty folder tag supposed to accomplish?
Rex M
It should returns folder, but I can't remember right now. SPList is a very complicated and obscure webservice, sometimes is magic... :)If it doesn't work, I'll check my docs here.
volothamp