Search This Blog

Friday, February 12, 2016

Working with SPQuery and CAML

As a sharepoint developer most of the people might have used SPQuery and CAML atleast once.

Writing a Basic Query

SPContext ctx = SPContext.Current;
using (SPSite site = new SPSite(ctx.Site.ID))
{
      using (SPWeb web = site.OpenWeb(webid))
      {
         SPList list = web.Lists["MyTestList];
         SPQuery query = new SPQuery();
         //You have to call GetItems function of SPlist to execute the CAML query
         SPListItemCollection items = list.GetItems(query);      
      }
}

Here it will return All the Items.But in real time we need to specify the conditions and attributes to fine tune the Results. We need to have basic understanding of CAML syntax inorder to take full advantage of SPQuery Object.If you have a CAMLBuilder tool then it will be always handy in writing CAML queries.You could douwnload CAML builder from here

Understanding SPQuery Properties

1. SPQuery.RowLimit
   This Property allows you to set how many rows you need in your result.Its quiet common that your Query could return more than 500 rows so its better to limit the number of rows in a result and use paging to retrive the rest of the result.I will explain paging below.

2. spquery.ViewAttributes

View attribute is one of the important attribute which is veryusefull to set how you are going to retrieve the Data.
  Scenario 1: You want retrieve all the items including items in folder and subfolders then set it like the following

 //If you want to return only file
          SPQuery.ViewAttributes = "Scope='Recursive'";   //If you want to return All items
          SPQuery.ViewAttributes = "Scope='RecursiveAll'";

  Scenerio 2 : You want retrive only files
          spquery.ViewAttributes = "Scope=\"FilesOnly\"";

  Scenario 3: Only Approved Items
         spquery.ViewAttributes = "ModerationType='HideUnapproved'"

3. SPQuery.Folder
   This property is usefull when you want to retrieve the data only from specific folder.In real world scenario you need to retrive the items from specific folder rather than retrieving all items in the list.
    SPQuery.Folder = folder; //It should be a SPFolder Object

 4.SPQuery.ViewFields
This property helps to set which are the fields /columns you want in the result.There is no point in returning all the coloumns.So its better practice to specify the fields you want to return.

     //Name is the coloumn name / internal name of the field
     SPQuery.ViewFields = "";

5. SPQuery.Query

This property used to set the real CAML query.Build your CAML string and assign to this property.

SPQuery.Query = String.Format("<Where>
                                                           <Eq>
                                                              <FieldRef Name=\'FileLeafRef\'/>
                                                              <Value Type=\"Text\"></Value>
                                                        </Eq>
                                                  </Where>", searchText);

//searchText is name of the file you want to search

Note : One thing here we have to remember is no need to add query tag in your XML.

If you are using Date time in your query then set includetimevalue = true. See Below

Query = "<Where><Eq><FieldRef Name='Modified'/><Value Type='DateTime' IncludeTimeValue='TRUE'>"+ LastCheckedDate + "</Value></Eq>
</Where>"

CAML Notations


•Eq = equal to
•Neq = not equal to
•BeginsWith = begins with
•Contains = contains
•Lt = less than
•Leq = less than or equal to
•Gt = greater than
•Geq = greater than or equal to
•IsNull = is null
•IsNotNull = is not null


Paging In SPQuery
Using paging with SPQuery is good practice.Its better to write code that will perform efficient way than giving bad user experience.

      using (SPSite site = new SPSite(SiteCollectionURL))
         {
                 
           using (SPWeb web = site.OpenWeb(WebName))
             {
              
               SPQuery query = new SPQuery();
               query.ViewAttributes = "Scope=\"Recursive\"";
               query.Folder = list.RootFolder;

               do
               {
                   SPListItemCollection listItems = list.GetItems(query);
                   
                 
 //Perform the operations you want
                   query.ListItemCollectionPosition = listItems.ListItemCollectionPosition;
                  
//If you are showing in a grid view then stor the listItems.ListItemCollectionPosition in
                  viewstate or something like that
               } while (query.ListItemCollectionPosition != null);
             }
         }

Limitation of SPQuery Object
You cannot use the SPquery object to query across multiple site collection instead use SPSiteDataQuery

Create dynamic SPQuery in Sharepoint


string myDynamicQuery = "<Eq><FieldRef Name=\"Author\" /><Value Type=\"User\">" + web.CurrentUser.Name.ToString() + "</Value></Eq>";

object[] distinctPostIds = GetDistinctPostIds(); 


for (int i = 0; i < distinctPostIds.Length; i++)
{
     strDynamicQuery = "<Or>" + myDynamicQuery + "<Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">" + distinctPostIds[i].ToString() + "</Value></Eq></Or>";
}

myDynamicQuery = "<Where>" + myDynamicQuery + "</Where><OrderBy><FieldRef Name=\"Created\" Ascending=\"False\" /></OrderBy>";


// Sample for multiple OR conditon:   
//<Where>
//<Or>
//<Or>
//<Or>
//<Or>
//        <Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">1</Value></Eq>
//        <Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">2</Value></Eq>
//</Or>
//        <Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">3</Value></Eq>
//</Or>
//        <Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">4</Value></Eq>
//</Or>
//        <Eq><FieldRef Name=\"ID\" /><Value Type=\"Counter\">6</Value></Eq>
//</Or>
//</Where>


SPQuery myQuery = new SPQuery();
myQuery.Query = myDynamicQuery;


Check for null values in CAML query


I have a custom list named "Custom" which has the following columns.

1.) Title
2.) Test

I need to use CAML query and get only the items which has null values in "Test" column.

Code snippet:

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Data;
using System.Globalization;

namespace ISNULL
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SPSite site = new SPSite("http://serverName/sites/Vijai"))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPList list = web.Lists.TryGetList("Custom");
                    SPQuery query = new SPQuery();
                    query.Query = "<Where><IsNull><FieldRef Name='Test' /></IsNull></Where>";
                    SPListItemCollection itemColl = list.GetItems(query);
                    foreach (SPListItem item in itemColl)
                    {
                        Console.WriteLine(item["Title"]);
                    }
                    Console.ReadLine();                 
                }
            }
        }
    }
}               

CAML Query Template

<Where>
    
<Or>
    
<Or>
    
<Or>
    
<Or>
        
<Eq>
            
<FieldRef Name=\"ID\" /><Value Type=\"Counte
\">
1</Value>
        
</Eq>
        
<Eq>
            
<FieldRef Name=\"ID\" /><Value Type=\"Counter\">2</Value>
        
</Eq>
    
</Or>
        
<Eq>
            
<FieldRef Name=\"ID\" /><Value Type=\"Counter\">3</Value>
        
</Eq>
    
</Or>
        
<Eq>
            
<FieldRef Name=\"ID\" /><Value Type=\"Counter\">4</Value>
        
</Eq>
    
</Or>
        
<Eq>
            
<FieldRef Name=\"ID\" /><Value Type=\"Counte
\">
6</Value>
        
</Eq>
    
</Or>

</
Where>

Get Top 5 list Items from Sharepoint List using CAML

This is a sample code for retrieving top 5 items from the SharePoint List.

SPQuery is the SharePoint class to initialize the CAML query.

This following Query will display the top 5 items OrderBy ID as Ascending is false.
using (SPSite objSite = new SPSite("<Site URL>"))
{
    using (SPWeb objWeb = objSite.OpenWeb())
   {
      SPList spList = objWeb.GetList("<List URL>");
      SPQuery spQuery = new SPQuery();
      spQuery.Query = "<Query>
      <OrderBy>
     <FieldRef Name='ID' Ascending='False' />
     </OrderBy> </Query> ";
     spQuery.RowLimit = 5;
     SPListItemCollection spListItemCollection = spList.GetItems(spQuery);
  }
}



Scopes in a CAML Query

Scopes in a CAML Query

I have been working for quite a while now with CAML queries and the scope is always something very important to bear in mind. How many times my queries returned nothing when I was sure they should bring back something…

Basically we have two modifiers Recursive and All and nothing, could we call nothing a modifier? All will bring back folders and files. Recursive will repeat the query in all the folders under the one we are working with.

If you don’t set the scope to All it will only bring files. If you don’t set it to recursive it will only retrieve items from the folder you are at. There are not that many variants so let’s make an example of each.

Let’s imagine we have a SharePoint folder like this one and we want to query it:

CamlScopeTreeSample

I am not good at paint, I know but what I want to show here is a tree where we have a Root folder (the root of the queries) and two sub-folders with files. For each scope possible I’ll highlight what you can expect to retrieve.

Just before we start, allow me to remind you that the scope is set in the property ViewAttributes of the SPQuery item.

To add a bit more of clarity I have also painted the levels:
CamlScopeTreeSampleLevels

The green line marks what’s inside the root folder, the blue line marks the contents of SubFolder1 and the red line SubFolder2.

ViewAttributes left by default:

CamlScopeByDefault
This is just the files under the root folder.

ViewAttributes = "Scope='Recursive'"

CamlScopeRecursive

This means all the files in all the folders.

ViewAttributes = "Scope='All'"

CamlScopeAll

This scope will bring folders and files under root.

ViewAttributes = "Scope='RecursiveAll'"

CamlScopeRecursiveAll

And finally with RecursiveAll you can bring back everything under the root entity.


ABCs of an EndPoint in WCF

This article is targeted to beginners in WCF. This is a totally theoretical article. It will explain:
  1. All the theoretical concepts of an EndPoint in WCF.
  2. Addresses in WCF
  3. Binding and where, which binding should be used.
  4. Contracts.
ABCs of Endpoints in WCF

The three elements of an endpoint starts with letters that make a mnemonic phrase.

"ABCs of Endpoints"

image1.gif


image2.gif
image3.gif

Address of an Endpoint(A)

image4.gif
  1. A address specifes where the service is residing.
  2. This is a Uniform Resource Locator (URL).
  3. The address URL identifies the location of the service.
  4. The address should folllow the "Web Service Addressing" (WS-Addressing) standard.

    image5.gif

    image6.gif
The address depends on whether it is hosted in IIS or a managed application or WAS. This also depends on the binding being used.

The following are example of various types of addresses:

image7.gif

Binding of an Endpoint (B)

The Binding is how the service is to be used. The Binding specifies:
  1. Which protocol to use.
  2. Which encoding to use.
  3. What type of security requeiremnets are to be used, like SSL or SOAP message security.
System provided Bindings
The system-provided Bindings are basicHttpBinding, wsHttpBinding, wsDualHttpBinding, webHttpBinding, wsFederationHttpBinding, netTCPBinding, netNamedPipeBinding, netMSMQBinding, netPeerTCPBinding, msmqIntegrationBinding, basicHttpContextBinding, netTCPContextBinding and wsHttpContextBinding.

The following describes basicHttpBinding:
  1. This is interoperable binding.
  2. This is commonly used as a replacement for earler web services based on ASMX.
  3. It supports HTTP & HTTPS protocols.
  4. It supports MTOM encoding.
  5. It supports text encoding.
The following describes wsHttpBinding:
  1. This is a secure binding.
  2. This is interoperable binding.
  3. This uses SOAP over HTTP.
  4. This supports reliability over internet.
  5. This supports transaction over internet.
  6. This supports security over internet.
  7. This supports HTTP/HTTPS proptcol
  8. This supports text and MTOM encoding.
  9. This is default binding provided by WCF.
The following describes wsDualHttpBinding:
  1. This supports all the features of wsHttpBinding.
  2. This is mainly used for DUPLEX SERVICE CONTRACTS.
  3. This supports bidirectional communication.
The following describes webHttpBinding:
  1. This is a secure binding.
  2. This is a interoperable binding.
  3. It supports Http/Https protocol.
  4. It does not use SOAP message format. 

    image8.gif
The following describes wsFederationHttpBinding:
  1. This is a secure Binding.
  2. This is interoperable binding.
  3. This supports federated security
  4. This supports Https/Https protocols.
  5. This uses text/MTOM encoding.

    image9.gif
The following describes netTCPBinding:
  1. This is a secure Binding.
  2. This could only be used if the client is also a WCF machine.
  3. This is used to send Binary encoded SOAP messages from one WCF computer to another.
  4. This uses Transimission Control Protocol (TCP).
  5. This supports reliability.
  6. This supports transaction.
  7. This supports security.
The following describes netNamedPipeBinding:
  1. This is a secure Binding.
  2. This could be used over a single WCF computer.
  3. This sends Binary encoded SOAP message over named pipes.
The following describes netMSMQBinding:
  1. This is a queued Binding.
  2. This uses Binary encoded SOAP message.
  3. This sends message over MSMQ.
  4. Here the communication should occur between two computers.
The following describes netPeerTCPBinding:
  1. This is a secure Binding.
  2. This uses TCP over peer to peer.
  3. The Communication should occur between two or more computers.
The following describes msmqIntegrationBinding:

image10.gif

basicHttpContextBinding
This Binding is the same as basicHttpBinding except with more attributes, as in the following:
  1. It supports HTTP cookies
  2. It eanbles SOAP haeders to exchange context.
  3. This binding is mainly used for Durable services.
netTCPContextBinding
This Binding is the same as netTCPBinding except with more attributes, as in the following
  1. It eanble SOAP haeders to excahnge context.
  2. This binding is mainly used for Durable services.
wsHttpContextBinding
This Binding is the same as wsHttpBinding with more attributes, as in the following:
  1. It eanble SOAP haeders to excahnge context.
  2. This binding is mainly used for Durable services.
Example :
<system.serviceModel>
                   <
services>
                             <
service name="WcfService2.Service1"behaviorConfiguration="WcfService2.Service1Behavior">                                      <!-- Service Endpoints -->
<endpoint  address="" binding="wsHttpBinding" contract="WcfService2.IService1">                                                <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          
-->
                                                <
identity>
                                                          <
dns value="localhost"/>                                                </identity>
                                      </
endpoint>
                                      <
endpoint address="mex" binding="mexHttpBinding"contract="IMetadataExchange"/>                             </service>
                   </
services>
                   <
behaviors>
                             <
serviceBehaviors>
                                      <
behavior name="WcfService2.Service1Behavior">                                                <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
                                                <
serviceMetadata httpGetEnabled="true"/>                                                <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
                                                <
serviceDebug includeExceptionDetailInFaults="false"/>                                      </behavior>
                             </
serviceBehaviors>
                   </
behaviors>          </system.serviceModel>
Contract of and EndPoint (C)

image12.gif
  1. The contract should be an Interface
  2. The contract could be a class also but the better approach is interface.
  3. In the config file this is preceded by prpject name space name
<endpoint  address="" binding="wsHttpBinding" contract="WcfService2.IService
                                       
            
                                                                               OR


EndPoint

WCF Service is a program that exposes a collection of Endpoints. Each Endpoint is a portal for communicating with the world.
All the WCF communications are take place through end point. End point consists of three components.

Address

Basically URL, specifies where this WCF service is hosted .Client will use this url to connect to the service. e.g
http://localhost:8090/MyService/SimpleCalculator.svc

Binding

Binding will describes how client will communicate with service. There are different protocols available for the WCF to communicate to the Client. You can mention the protocol type based on your requirements.
A binding has several characteristics, including the following:
  • Transport -Defines the base protocol to be used like HTTP, Named Pipes, TCP, and MSMQ are some type of protocols.
  • Encoding (Optional) - Three types of encoding are available-Text, Binary, or Message Transmission Optimization Mechanism (MTOM). MTOM is an interoperable message format that allows the effective transmission of attachments or large messages (greater than 64K).
  • Protocol(Optional) - Defines information to be used in the binding such as Security, transaction or reliable messaging capability
The following table gives some list of protocols supported by WCF binding.
BindingDescription
BasicHttpBindingBasic Web service communication. No security by default
WSHttpBindingWeb services with WS-* support. Supports transactions
WSDualHttpBindingWeb services with duplex contract and transaction support
WSFederationHttpBindingWeb services with federated security. Supports transactions
MsmqIntegrationBindingCommunication directly with MSMQ applications. Supports transactions
NetMsmqBindingCommunication between WCF applications by using queuing. Supports transactions
NetNamedPipeBindingCommunication between WCF applications on same computer. Supports duplex contracts and transactions
NetPeerTcpBindingCommunication between computers across peer-to-peer services. Supports duplex contracts
NetTcpBindingCommunication between WCF applications across computers. Supports duplex contracts and transactions

Contract

Collection of operation that specifies what the endpoint will communicate with outside world. Usually name of the Interface will be mentioned in the Contract, so the client application will be aware of the operations which are exposed to the client. Each operation is a simple exchange pattern such as one-way, duplex and request/reply.
Below figure illustrate the functions of Endpoint

Example:

Endpoints will be mentioned in the web.config file on the created service.
<system.serviceModel>
<services>
      <service name="MathService"
        behaviorConfiguration="MathServiceBehavior">
       <endpoint
         address="http://localhost:8090/MyService/MathService.svc" contract="IMathService"
          binding="wsHttpBinding"/> 
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MathServiceBehavior">
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>