SharePoint: Validating SPQuery - sharepoint

I am writing an internal API for my company which allows users to pass in SharePoint CAML query.
In side my function I take to user's query, and add some additional elements to it and then use the final query to retrieve required data from SharePoint.
Example:
User passes in:
<Query>
<Where>
<Eq>
<FieldRef Name='Category' />
<Value Type='Choice'>Bug</Value>
</Eq>
</Where>
</Query>
Internally, I modify the query to be:
<Query>
<Where>
<And>
<Eq>
<FieldRef Name='Category' />
<Value Type='Choice'>Bug</Value>
</Eq>
<Eq>
<FieldRef Name='AssignedTo' />
<Value Type='Integer'><UserID /></Value>
</Eq>
</And>
</Where>
</Query>
What do you think is the best way to validate queries sent by users?

If the queries that you're going to allow are fairly restricted, it might be a good approach to build a schema to represent what a valid query would be. Then you could just see if their xml is valid according to that schema. Also, I know that you can use the CAML Builder dll from code. I can't find an example of this right away, but there may be a way to use it's CAML building methods in a try/catch block to stop invalid queries from ever getting built.
Also, it occurs to me that you may need to watch out for the fact that the CAML query's FieldRef will need to be built using the internal name of the field which may differ from the display name.

Related

Properly Nesting Compound AND / OR Statements Using CAML

I am leveraging SPservices within a SharePoint 2013 environment to create filtered views unique to the current user. Effectively, when a user visits a page, they get a custom feed of documents that they have uploaded to a specific library.
I can successfully query the library and render the results they way I want, but when I attempt to create a compound CAML query, I keep getting errors. I have tried using the various resources here to manually build this query (and do to network restrictions I cannot use the U2U CAML builder tool), but I keep getting thrown errors. I started doing simple queries and it was working, but once I try to get to my third and forth "OR" statements (including a IsNull argument), I hit a wall. I think I am improperly nesting my statements and would love some help in identifying what I am doing wrong.
<Where>
<And>
<Contains>
<FieldRef Name='Author' />
<Value Type='User'>" + userName + "</Value>
</Contains>
<And>
<Eq>
<FieldRef Name='ContentType' />
<Value Type='Computed'>Document</Value>
</Eq>
</And>
<Or>
<Or>
<Or>
<Or>
<Eq>
<FieldRef Name='sensitivity' />
<Value Type='Choice'>Low</Value>
</Eq>
<Eq>
<FieldRef Name='sensitivity' />
<Value Type='Choice'>Medium</Value>
</Eq>
</Or>
<Eq>
<FieldRef Name='sensitivity' />
<Value Type='Choice'>High</Value>
</Eq>
</Or>
</Or>
<IsNull>
<FieldRef Name='sensitivity' />
</IsNull>
</Or>
</And>
</Where>
The desired result would be an output of items that the current user uploaded / created WHERE the Content Type is equal to "Document" AND the Sensitivity (choice) field is equal to Low, Medium, High or is empty.
I feel like I am really close, but I am making a silly mistake. For context, the "userName" reference in the statement is a javascript variable that is functioning properly.
The bracketing can be quite confusing without a tool like the U2U CAML builder tool. I feel your pain.
I think your issue may be the isnull at the end. I believe you would want is NotNull
<IsNotNull>
<FieldRef Name='sensitivity' />
</IsNotNull>
As a last ditch you might be able to just query all files by user whos documents co

SharePoint 2013 CAML query OrderBy not sorting properly

I'm using a CAML query to grab some items from a list. It pulls the items into a datatable which is then set as the datasource of a gridview control.
Everything worked fine until I realized it was using the ID field to sort the items. I wanted to sort by the field Target_x0020_Id, so I ordered the order by, however it doesn't change the behavior when I added this.
This is my query:
WhereEqFieldRefName='Target_x0020_Id' Value Type='Text'900/Value/EqWhereOrderByFieldRef Name='Target_x0020_Id'/FieldRef/OrderBy
The only thing I added was the orderby element. (Sorry I'm having some issues posting the code without it trying to render in the post)
I can only assume this is the CAML you're using
<Where>
<Eq>
<FieldRefName='Target_x0020_Id'>
<Value Type='Text'>900</Value>
</Eq>
<Where>
<OrderBy>
<FieldRef Name='Target_x0020_Id'></FieldRef>
</OrderBy>
I see three glaring errors.
There's a missing space between FieldRef and Name in the <Eq> portion of the caml.
The closing <where> is missing the forward slash.
The FieldRef tag in <OrderBy> is incorrect. It's self closing
This should be the right caml
<Where>
<Eq>
<FieldRef Name='Target_x0020_Id'>
<Value Type='Text'>900</Value>
</Eq>
</Where>
<OrderBy>
<FieldRef Name='Target_x0020_Id' />
</OrderBy>
I do see that you're returning all items where Target_x0020_Id is equal to 900 and then sorting all those items by Target_x0020_Id. Since this field is always 900, your sort isn't going to work.
Also, is Target_x0020_Id really a text field? If it's numeric, you should chagne the type to 'Number' instead of 'Text'.

CAML Query for multiple branches of "And-Or-In" statements

I'm using CAML Query to pull items from a list.
I tried re-arranging the structure of my query, and still would not return anything. I try not to use CAMLQuery Builder (doing it manually).
<Query>
<Where>
<And>
<Contains>
<FieldRef Name="Field1"/><Value Type="Text">A</Value>
</Contains>
<And>
<In>
<FieldRef Name="Field2"/><Values><Value Type="Text">B</Value></Values>
</In>
<Or>
<In>
<FieldRef Name="Field3"/><Values><Value Type="Text">C</Value></Values>
</In>
<In>
<FieldRef Name="Field4"/><Values><Value Type="Text">D</Value></Values>
</In>
</Or>
</And>
</And>
</Where>
</Query>
Note: I have seen questions that may seem as a duplicate of this, but have never seen a question go as deep as this level of branching. CAML Query seems to be particular in where you put your closing tags.
Did I nest my "And" and "Or" incorrectly? What could be wrong/missing in this query?
While your CAML appears valid to me (without actual <FieldRef> and <Value> elements, I can't specifically test your field names, types & values), I tend to write my CAML in a more "balanced" fashion, as such:
<Query>
<Where>
<And>
<And>
<Contains>A</Contains>
<In>B</In>
</And>
<Or>
<In>C</In>
<In>D</In>
</Or>
</And>
</Where>
</Query>
According to the spec, both your posted version & my answer here would net the same result, but I would test to confirm. If the above doesn't work, brevity aside, I'd suggest posting your full CAML so that we can recreate your List with the same field names & types and test data with matching values.

Sharepoint Web Service Query

I'm creating an iOS app that queries a Sharepoint Webservice with GetListItems. I'm able to retrieve all of the records, but there are a lot of records > 4000. Is there a way I can retrieve 50 at a time?
I'm using SOAP for this by the way.
Assuming you're passing a CAML query to the webservice, you ca use a rowlimit tag
<Query>
<!-- your current query here -->
<RowLimit>100</RowLimit>
</Query>
EDIT
To retrieve a subset of values you could do something like this
<Query>
<Where>
<And>
<Geq>
<FieldRef Name='ID'/>
<Value Type='Counter'>0</Value>
</Geq>
<Lt>
<FieldRef Name='ID'/>
<Value Type='Counter'>100</Value>
</Lt>
</And>
</Where>
</Query>
I haven't tested this, but it should work. Of course, you're going to want to change the values in your code to retrieve the particular subset.

how to make sharepoint CAML query works more efficienctly

I am now working on sharepoint CAML query. to fetch out item by a given name from a huge resources library which full of images, documents, videos and so on.
I didn't know whether sharepoint index the Name column. I'm thinking to use nested query to make this query faster.
My question here is:
How does sharepoint query work? execute the outer layer first, or start from the inner layer?
I wanna to filter the ResourceType(Image,Document..) first. then filter the category and finally fetch out the items match the name.Is the query bellow work just like what i need?
<Where>
<And>
<Eq><FieldRef Name='IR_ResourcesType' />
<Value Type='Text'>Image</Value></Eq>
<And>
<Eq><FieldRef Name='IR_Category' />
<Value Type='Text'>All</Value>
</Eq>
<Eq>
<FieldRef Name='FileLeafRef' />
<Value Type='File'>aaa</Value>
</Eq>
</And>
</And>
</Where>
If you can, try indexing one of the unique columns in your list so you can use it later on for querying in your where clause.
As best practice, we should also just get the columns that we will be using so as to not have a data buffet. You can limit the columns you will be displaying by using viewFields.
Here is a link which shows some tips and tricks for CAML in conjunction with SPServices which I think you might find useful.

Resources