Pages

Jul 19, 2011

Redirecting to Access Denied Page

If you want to follow the same behavior as SharePoint in your custom web parts, if the user does not meet the security criteria for the current page you should redirect to Access Denied Page.
In order to achieve that you can use HandleAccessDenied method of SPSecurity.
The code bellow shows how to use HandleAccessDenied to redirect to Access Denied Page:
SPUtility.HandleAccessDenied(new Exception("You are not authorized to perform this operation."));

pri

SharePoint 2010 Governance Planning and Implementation

Why do you need a Governance Plan?
  • Scott indicated that 20% of a successful solution implementation is about Technology, but about 95% of the Governance documentation is about Technology.  We need to be prepared for the other 80%.
  • Users need to be trained appropriately before being empowered with the control of the system.
    • People do not treat SharePoint like an Enterprise Application
    • Letting users add unlimited items to a list – can kill the server
    • Not Planning for scale and growth
    • Users can do a lot – we give them “great power” and need to ensure they accept their “great responsibility”
    • Many of SharePoint’s capabilities are not required or mandated, so if you mess it up, there is a work around for them (e.g. they will collaborate through email if you don’t get SharePoint collaboration correct).
What Does Governance mean in the context of SharePoint?
  • Your Governance Plan defines people roles, technology and policy guidelines and process to resolve ambiguity.
    • People – Define clear roles and responsibilities
    • Technology – Define policies for service levels and appropriate use
    • Policy – Articulate design and usage principles
      • In 2010, how will people feel if they give someone a rating of 1 (out of 5) for someone else’s document
  • Process – For example provisioning a site
Define a Vision – Don’t think about requirements from the start, but instead, talk about the “outcomes” (what are you trying to achieve).  Requirements can be derived from the desired outcome.  The Governance Plan will help support the Vision
People Roles
  • Get the right people in place (MOSS introduced many new roles that were required, but most organizations didn’t assign people to these roles.  Take the rollout of SharePoint 2010 as an opportunity to get people assigned to these roles. Most of these roles are NOT full time, and one person can fill more than one role.)
    • Executive Sponsor
    • Governance Board / Steering Committee
    • Business Owner
    • Solution Administrator
    • Technology Support Team
    • Site Sponsor / Owner
    • Site Steward
    • User
    • The management of Enterprise Corporate Taxonomy in SharePoint 2010 will need to have an owner (even though other may be allowed to update the data).
Governance Model – An Overview of the Governance Model created by Microsoft was presented.
Guiding Principles
  • Publish Once, Link Many
  • No Email attachments – Send links
  • In 2007 Use Metadata not folders – In 2010 Use Folders to inherit metadata.
    • NOTE The concept of using folders in SharePoint 2010 is a paradigm shift that IT and end users will need to understand and utilize.
    • Content management is everyone’s responsibility but site owners are accountable
Tactics for Successful Roll-out and Strategy
  • Fun and engaging launch event
    • Example, Birth announcement of SharePoint, Scavenger Hunt for content within the site
    • Lunch-n-learns
    • Power Users Community of Practice – Power users teach others
Content Management Plan – Is changing a column on a list code or content?  Who is allowed to make these changes?  Is SharePoint Designer workflow code or content?  There will be even more decisions like this to be made with the rollout of SharePoint 2010.
Governance Plan Document
  • Break documents into chunks
    • Vision
    • Roles and Responsibilities
    • Guiding Principles
    • Policies
    • Guidelines/Best Practices
    • Procedures
    • Do not include
      • Implementation Details
      • Network Requirements
      • Feature Requirements
Tip: The actual “process” of creating the document is more important than the actual document itself.  Make sure to include Human Resources (e.g. what can people post on blogs, put on their MySite, etc.).  Everyone wants SharePoint, but no one wants to take responsibility for it.  So the actual process, of arriving at decisions is the most important part.
Governance Details for SharePoint 2010
  • Social Computing Implications
    • Rating of documents (especially a low rating) may cause people to shy away from loading documents.  Note that changing the wording of the rankings may be able to help in this regard.
    • MySites – Posting information that people will judge you on within the organization, or you may shy away
  • Managed Metadata
    • Managed Keyword vs. Managed Term
      • Managed Keywords – Allow users to key in phrases or key words (that have edit rights) on an item – they can type in whatever they want. 
      • Managed Terms – Based off of the master hierarchy/taxonomy values
      • Social Tags – Even though you do not have edit rights to this content, anyone can “socially tag” this content
      • NOTE: The distinction of these terms is confusing and will need to be better understood by the SharePoint owners, so that it can be explained to end users, and what access an end user will be able to utilize.
  • Records Management
    • In-Place Records vs. Records Archive
      • Organizations will probably use both
  • Resource Governor
    • More than 5,000 items in list, SharePoint won’t return
    • Need to communicate / educate users about this
  • Content Organizer
    • Used to partition/route documents based on metadata
    • Need to communicate / educate users where their documents are going
  • SharePoint Customizations
    • SharePoint Designer – On or Off
    • SODA – SharePoint On-Demand Applications
    • Excel and Access Solutions – Turn this on or off?
    • Sandbox Solutions

Jun 24, 2011

Sharepoint 2007 Calendar Color Coding.

For color coding refer to blog . But for further enhancements see below information.



J-query refer it from you document library.


<script src="/Documents/jquery-1.3.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function()
{
//setting the row width for each and every bloc
$("td.ms-cal-monthitem").each(function()
{
var row1 = $("td.ms-cal-monthitem").parent();
var table1 =row1.parent().parent();
 table1.width('100%');
});
//hiding the time
$("td.ms-cal-monthitem").each(function()
{

if( $(this).html().indexOf('<NOBR') != -1)
  {
    var left = $(this).html().indexOf('<NOBR');
    var right = $(this).html().indexOf('</NOBR>')
    var string = $(this).html().substring(left,right+7);
     var calHTML =$(this).html();
    var newHTML = calHTML.replace(string,'');
   $(this).html(newHTML);
     }
});
});</script>

Jun 21, 2011

.Net 4.0 Advance Training.....!

Today i went to inhouse training on the  below topics. But as a SharePoint Developer not sure where to inject this topics (except WWF).....?


Topic
Code Contracts
Design-Time-Only Interop Assemblies
Dynamic Language Runtime
Covariance and Contravariance in Generics
BigInteger and Complex Numbers
Tuples
Memory-Mapped Files
Managed Extensibility Framework
Parallel Computing
WWF

Jun 20, 2011

Claims Based Authentication using ADFS 2.0


SharePoint 2010 has made available a very useful type of authentication called Claims based Authentication. You can have a custom identity provider and make your web application use that identity provider in the places of default Windows Authentication. You can also make it use multiple authentication providers. Following are the steps to be followed for configuring a SharePoint 2010 web application to use Claims Based Authentication.
I will use ADFS 2.0 to authenticate users in my domain instead of Windows Authentication. 

INSTALL AND CONFIGURE ADFS 2.0

  1. Install ADFS 2.0 on the server which can authenticate the users.
  2. Run the ADFS configuration wizard.
  3. Select create new federation server if you are using this for testing or else select the appropriate option.
  4. If you plan to use more than one ADFS select New Federation Server Farm else select Stand Alone Server. Click Next
  5. The wizard automatically picks up a certificate. If it show any error. Go to IIS manager and create a certificate with Fully Qualified Domain Name (FQDN) and run the wizard again.
  6. Give the credentials for the service account and click next.

CREATE RELYING PARTY TRUST.

  1. Open the ADFS 2.0 management console and expand on Trust Relations
  2. Select Relying Party Trust
  3. Click on Add Relying Party trust.
  4. Select enter data about relying party manually.
6. Select ADFS 2.0 profile and click next.
7. Selecting a certificate for encryption is optional. Click next.
8. Select Enable support for WS-Federation Passive Protocol. Give the url of your web application with /_trust/ at the end
Example (https://servername:port/_trust/)
Note: Do not forget to give the slash “/” at the end after trust (/_trust/)
              9. Click next


  1. Do not add any identifiers. Click next.
  2. Select permit all users to access this relying party. Click next.
  3. Verify the configuration and click next at the following screen.
  4. Leave the check box “Open the edit claim rules dialog…” and click on Close.
  5. Then click on Add rules.
     15. Select the claim rule template as “Send LDAP attributes as claims” 
     16. Give a name for the claim rule. Select Active Directory as attribute store. 
    Click on the dropdown and select SAM Account Name in the LDAP attribute 
    Select E-Mail address as the outgoing claim type. 
    In the next row select Token Groups – Unqualified Names as LDAP attribute 
    Select Role as the outgoing claim type.

    EXPORT CERTIFICATE

    1. Open ADFS 2.0 management console.
    2. Expand Service and select Certificates.
    3. Right click on Token Signing Certificate and select view certificate.
    4. In the Certificate windows select Details tab and click on copy to file.

     

    1. In the Certificate Export wizard click next.
    2. Select DER encoded binary X.509 and click next.
    3. Give a location where you want to save the exported certificate.
    4. Click on finish.
    5. Copy this certificate to the server where the SharePoint server is installed.
    6. Central Admin-> Security -> Manage Trust and click New
    7. Upload the token signing certificate which you copied from the ADFS server.

      Configure a Claims-based Web application

      THE CONFIGURATION OF A CLAIMS-BASED SHAREPOINT WEB APPLICATION CAN BE ACHIEVED USING WINDOWS POWERSHELL. THE STEPS TO BE FOLLOWED ARE AS FOLLOWS


      1. From the Windows Power Shell command prompt (PS C:\>), create an x509Certificate2 object using the following code:
      $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("path to cert file")
      1. Create a claim type mapping to use in your trusted authentication provider using the following code
      New-SPClaimTypeMapping "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"-IncomingClaimTypeDisplayName "EmailAddress" –SameAsIncoming
      1. Create a trusted login provider by first creating a value for the realm parameter using the following code
      $realm = "https://serevrname:port/_trust/"
      1. Create a value for the signinurl parameter that points to the Security Token Service Web application using the following code
      $signinurl = "https://sysname/adfs/ls/”
      1. Create the trusted login provider, using the same IdentifierClaim value as in a claim mapping ($map1.InputClaimType) using the following code.
      $ap = New-SPTrustedIdentityTokenIssuer –Name "ClaimsProvider" -Description "My Custom Identity Provider" –Realm $realm -ImportTrustCertificate $cert -ClaimsMappings $map1[,$map2..] –SignInUrl $signinurl -IdentifierClaim $map1.InputClaimType
      This completes the process of configuring SharePoint application with Claims based authentication

      Change the authentication for the SharePoint application

      1. GO TO CENTRAL ADMINISTRATION AND GO TO MANAGE WEB APPLICATIONS PAGE IN APPLICATION MANAGEMENT.

      2. Select the Web application for which you want to enable Claims based authentication. This should be running in the port number you specified while configuring the identity provider and the relying party.
      3. Click on the Authentication Providers and click on the Claims Based Authentication.
        4. In the dialog box, scroll the authentication providers and select Trusted Identity Providers. 
        5. That will enable the ClaimsProvider which we have created in the earlier step.
        1. Select the provider and click Ok.
        2. Create a site collection in the web application.
        3. To add the site collection administrator, click on the People picker and type the complete the email address of the user.
        4. Now you should be able select the authentication provider from Windows Authentication and ClaimsProvider when you browse the site.
        5. You can remove Windows authentication from the Authentication Providers if you don’t need it. 

That completes the process of enabling Claims Authentication for SharePoint sites.

Application Vs. Content Pages in SharePoint


Today my friend posted a simple question but might be tricky, so i thought to post it will be useful for interviews.
SharePoint has two types of ASPX pages. One type is the application page, also known as a _layout page. The other type of ASPX page is a content page, also known as a site page. Each of these page types is stored in a different location in SharePoint. When developers create custom ASPX pages, they must decide on the page type.
Content Pages or Site Pages:
Content pages or Site pages are basically built to display and manage site content. Content pages can be customized by end users from within the SharePoint user interface or with Microsoft Office SharePoint Designer. When you create a SharePoint site, many content pages are created automatically, for example, home page (default.aspx) of the as well as the pages associated with lists and document libraries, such as AllItems.aspx, NewForm.aspx, and EditForm.aspx, and several others. Logically all content pages are stored within their SharePoint sites. Physically all the content pages that have not been customized, also known as uncustomized or ghosted pages, are stored on disk on the front-end Web server, while content pages that have been customized, also known as customized or unghosted pages, are stored in their associated SharePoint content database.
Content pages do not support in-line server side code under the default security policy enforced by Windows SharePoint Services. But there is a way to override the WSS settings to allow the in-line server side code in content pages. But even after overriding WSS settings, the in-line server side code will be supported on content pages only if that content page is not customized.
Application Pages or _layout Pages:
Application pages or _layout page are basically built for site management activities. Application pages does not support customization and typically created to allow users to manage settings for lists, sites, and site collections. Application pages are stored typically in the file system of the front-end Web server within a directory "c:\program files\common files\microsoft shared\web server extensions\12\TEMPLATE\LAYOUTS". settings.aspx, viewlsts.aspx, etc. are few examples of application pages which you can find in the layouts directory.
Application pages are available across the server farm which allows these pages to run on any site collection in the farm. When you create a new SharePoint web application, it creates a new website in the IIS. If you look at the created website in the IIS, you can see that SharePoint automatically created a virtual directory name "_layouts" which is mapped to the physical LAYOUTS directory i.e. "c:\program files\common files\microsoft shared\web server extensions\12\TEMPLATE\LAYOUTS". By using this mapping scheme along with some additional processing logic, the WSS runtime can make each application page accessible within the context of any site in the farm.
An application page, such as settings.aspx, can be accessed by adding its relative path within the _layouts directory to the end of a site’s URL. For example, you can access the Site Setting page by using the URL "http://sitename.com/_layouts/settings.aspx".
Application pages, unlike content pages, supports in-line server side code but cannot host SharePoint features such as dynamic Web Parts and Web Part Zones.

Jun 18, 2011

CAML Story in SHARE-POINT.............


Writing CAML Queries For Retrieving List Items from a SharePoint List...........

Introduction

The Collaborative Application Markup Language (better known as CAML) is an XML-based query language that helps you querying, building and customizing Web sites based on Windows SharePoint Services. The XML elements define various aspects of a WSS site.
In this first series of articles I will explain in detail how to build and execute CAML queries to retrieve list items from a SharePoint list. List items can be retrieved in several different ways: using the SharePoint object model, using the SharePoint Lists web service or even by using Powershell. Use the SharePoint object model when your code runs on the server (like f.e. when you’re developing a web part or an application page). Use the SharePoint Web Services when your code doesn’t run on the server where SharePointis installed, for example when you develop office clients or windows applications. Powershell, at the other side, can be used by administrators when they quickly need to retrieve some information. In any way the CAML query is the same.

Building the CAML

CAML is an XML-based query language. Its root element is Query. Within the Query element two other elements are possible but not required: the OrderBy element and the Where element.
The OrderBy element is the simplest one. It is used to sort the returning list items. You have to specify the field(s) on which you want to sort the items and the sort direction. The syntax looks as follows:
<OrderBy>
   <FieldRef Name='LastName' Ascending='False' />
</OrderBy>
The OrderBy clause is not required and you can specify one or more fields on which you want to sort. If you omit the Ascending attribute, your resulting rows will be sorted in ascending order. If you want to order in descending order you have to specify Ascending=’False’.
The Where clause is used to specify one or more filter criteria. This clause can be very simple but can end up being rather complex. In its most simple form you specify an operator, a field name for which you want to specify a criterion, and a value.
<Where>
   <Eq>
     <FieldRef Name='LastName' />
      <Value Type='Text'>Janssens</Value>
  </Eq>
</Where>

Operators

You have different operators:
Eq                     Equals
Neq                  Not equal
Gt                     Greater than
Geq                    Greater than or equal
Lt                      Lower than
Leq                     Lower than or equal too
IsNull                Is null
BeginsWith     Begins with
Contains          Contains

Fields

The FieldRef element can be any field of the list on which you want to execute the CAML query. If you use the Name attribute you need to specify the internal name of the field. But you can also use the IDattribute to specify the Guid of the field.

Value

The Valueelement specifies the value part of the criterion. The attribute Typeis optional and specifies the data type of the field you want to specify the criterion for. If omitted the data type is considered as beingText. In all other cases you have to specify the Type attribute. DateTime fields are a special case and will be described in more detail later in this article.
If the field type is a Lookup you need to specify the text value.For example you have an Employees list and the Country field is a lookup field referring to the Countries list. In that case an employee living in Belgium will have f.e. following value: #15;Belgium. If you have to query for the employees living in Belgium you will have to write your query as follows:
<Where>
    <Eq>
     <FieldRef Name='Country' />
     <Value Type='Lookup'>Belgium</Value>
  </Eq>
</Where>
You can find this not good coding practice because the name of the country can change in time. In that case you can also query on the id of the country specifying the LookupId attribute in the FieldRefelement:
<Where>
  <Eq>
     <FieldRef Name='Country' LookupId='True' />
     <Value Type='Lookup'>15</Value>
  </Eq>
</Where>
If you want to specify two filter criteria you also have to specify a join operator And or Or.
<Where>
   <And>
      <Eq>
        <FieldRef Name='LastName' />
        <Value Type='Text'>Janssens</Value>
     </Eq>
     <Geq>
        <FieldRef Name='Age' />
        <Value Type='Number'>21</Value>
     </Geq>
   </And>
</Where>
If you want to specify more filter criteria you have to nest them in a very specific way:
   <Where>
    <And>
        <And>
           <Eq>
             <FieldRef Name='LastName' />
             <Value Type='Text'>Janssens</Value>
           </Eq>
           <Geq>
             <FieldRef Name='Age' />
             <Value Type='Number'>21</Value>
           </Geq>
        </And>
        <Lt>
          <FieldRef Name='Age' />
          <Value Type='Number'>60</Value>
        </Lt>
    <And>
   </Where>
For each extra criterion you have to add an extra join operator at the outside of the query and add the criterion at the end:
    <Where>
    <And>
       <And>
           <And>
              <Eq>
                <FieldRef Name='LastName' />
                <Value Type='Text'>Janssens</Value>
              </Eq>
              <Geq>
                <FieldRef Name='Age' />
                <Value Type='Number'>21</Value>
              </Geq>
           </And>
           <Lt>
             <FieldRef Name='Age' />
             <Value Type='Number'>60</Value>
           </Lt>
       </And>
        <Eq>
          <FieldRef Name='Country' />
          <Value Type='Lookup'>Belgium</Value>
        </Lt>
    </And>
   </Where>

Retrieving List Items with CAML using the SharePoint Object Model

If you need to retrieve items from a list when developing web parts, application pages or custom field types you can best use the SPQueryobject from the SharePoint object model. This object is located in theMicrosoft.SharePoint namespace of the Microsoft.SharePoint.dll located in the Global Assembly Cache.
Instantiate the object as follows:
SPQuery qry = new SPQuery();
The most important property is the Query property, which needs to be set to your CAML query:
string camlquery = "<OrderBy><FieldRef Name='Country' /></OrderBy><Where>"
    + "<Eq><FieldRef Name='LastName' /><Value Type='Text'>Smith</Value></Eq>"
    + </Where>";
qry.Query = camlquery;
At this point you can execute the query on your list:
SPListItemCollection listItemsCollection = list.GetItems(qry);
A small remark with the GetItems method of the SPList instance: this method returns a collection of typeSPListItemCollection. It is possible that it is easier working with a DataTable. In that case you can execute the query as follows:
DataTable listItemsTable = list.GetItems(qry).GetDataTable();
The query will not only return all list items that have their last name set to Smith, but also all columns of each list item. In cases you work with large lists it can be important to retrieve a subset of list items containing only the columns you need. In that case you will have to set the ViewFields property of theSPQuery object. You can do this by specifying all columns you want to see returned:
qry.ViewFields = "<FieldRef Name='FirstName' /><FieldRef Name='LastName' />";
This will return the first name and the last name of the retrieved employees, but also the system fields like the ID and the Created date.
The major disadvantage of the SPQuery object is that you can query only one list. If you want to query more than one list you will have to use the SPSiteDataQuery. More on this object in a later article because it earns special attention.
It is common knowledge by now but let me remind you that it’s always a good idea to use SPQuery to retrieve a subset of list items. You can loop through the list item collection to find the list items that match your needs but this will have a serious negative impact on the performance of your work.

Retrieving List Items with CAML using the SharePoint Web Services

If you are developing office clients or any other application that will not run on the server where SharePoint is installed you will need to use the SharePoint Web Services to retrieve (or update) information from SharePoint. If you want to query a list you will need to execute the GetListItems method from theLists.asmxSharePoint web service.
Working with the SharePoint web services is different in Visual Studio 2005 then in Visual Studio 2008.

Retrieving List Items from the Lists.asmx using Visual Studio 2005

First you have to reference  the web service in your Visual Studio project. If you work with Visual Studio 2005 you have to add a Web Reference to theLists.asmx.
Then you have to instantiate the web service and pass the url of the SharePoint site, plus the location and name of the SharePoint web service. The SharePoint web services are all located in the ISAPI directory of the SharePoint 12 hive but are accessible from outside via the _vti_bin directory.
Initialize the Lists.asmx web service:
 ListService listsWs = new ListService.Lists();
listsWs.Url = siteUrl + @"/_vti_bin/lists.asmx";
Then you have to set the credentials. In case you don’t need to specify a username or password you can proceed as follows:
listsWs.Credentials = System.Net.CredentialCache.DefaultCredentials;
If you have to specify a user name and password:
listsWs.Credentials = new System.Net.NetworkCredential(userName, password);
If you also have to specify a domain, use the other overload:
listsWs.Credentials = new System.Net.NetworkCredential(userName, password, domain);
Then you are ready to call the GetListItems method, which requires the following syntax:
resultNode = _sharepointSite.ListsWSS.GetListItems(listName, viewName,
    queryNode, viewFieldsNode, rowLimit, queryOptionsNode, webID);
Not all arguments are required. Arguments like view name, row limit and web ID are optional.
The query node argument will contain the CAML query as explained in previous sections but need to be enclosed within a <Query> and </Query> tag:
XmlDocument camlDocument = new XmlDocument();
XmlNode queryNode = camlDocument.CreateElement("Query");
queryNode.InnerXml = "<OrderBy><FieldRef Name='Country' /></OrderBy><Where>"
    + "<Eq><FieldRef Name='LastName' /><Value Type='Text'>Smith</Value></Eq>"
    + </Where>";
The same applies to the ViewFields node:
XmlNode viewFieldsNode = camlDocument.CreateElement("ViewFields");
viewFieldsNode.InnerXml = "<FieldRef Name='FirstName' />"
    + "<FieldRef Name='LastName' />";
As you will have noticed, you also need a QueryOptions node. This node will be explained later in this series. If you have no QueryOptions to specify you can pass in an empty node:
XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");

Retrieving List Items from the Lists.asmx using Visual Studio 2008

But in case you are working with Visual Studio 2008 you will have to add a Service Reference to theLists.asmxweb service. If you don’t want to work asynchronously you have to uncheck the Generate Asynchronous Operations option in the Advanced dialog. When closing the dialog box Visual Studio automatically adds an app.config or web.config file. Open this file and locate the security section. The following XML is generated automatically:
<security mode="None">
    <transport clientCredentialType="None" proxyCredentialType="None"
        realm="" />
    <message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
Replace it with the following:
<security mode="TransportCredentialOnly">
  <transport clientCredentialType="Ntlm"/>
</security>
Return to your code and instantiate the web service:
ListsWS.ListsSoapClient ws = new ListsWS.ListsSoapClient();
You also have to set the necessary credentials. If you can work with the default credentials you can write the following:
 ws.ClientCredentials.Windows.ClientCredential =
       System.Net.CredentialCache.DefaultNetworkCredentials;
 ws.ClientCredentials.Windows.AllowedImpersonationLevel =
       System.Security.Principal.TokenImpersonationLevel.Impersonation;
If necessary you can also pass user name, password and domain:
 ws.ClientCredentials.Windows.ClientCredential =
       new System.Net.NetworkCredential("Administrator", "secret", "U2UCOURSE");
 ws.ClientCredentials.Windows.AllowedImpersonationLevel =
       System.Security.Principal.TokenImpersonationLevel.Impersonation;
If necessary you can set the URL to the web service dynamically:
 ws.Endpoint.Address =
     new System.ServiceModel.EndpointAddress(
     "http://wss.u2ucourse.com/_vti_bin/lists.asmx");
Now you are ready to call the GetListItems method of the web service. There is no difference in calling this method from within Visual Studio 2005:
XmlDocument camlDocument = new XmlDocument();
 XmlNode queryNode = camlDocument.CreateElement("Query");
queryNode.InnerXml = "<OrderBy><FieldRef Name='Country' /></OrderBy><Where>"
    + "<Eq><FieldRef Name='LastName' /><Value Type='Text'>Smith</Value></Eq>"
    + </Where>";
 XmlNode viewFieldsNode = camlDocument.CreateElement("ViewFields");
viewFieldsNode.InnerXml = "<FieldRef Name='FirstName' />"
    + "<FieldRef Name='LastName' />";
 XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");
 resultNode = _sharepointSite.ListsWSS.GetListItems(listName, viewName,
    queryNode, viewFieldsNode, rowLimit, queryOptionsNode, webID);
The returned XML is rather complex and needs some special attention. I will come back on this in a later article.

Query Options

Executing a query is not only about CAML. When working with the SPQuery object you can set different properties to influence the returned list items. When working with the SharePoint web services, these options are translated into CAML and are part of the QueryOptions element.

RowLimit

Setting this property limits the number of rows returned in the result set.
When working with the SPQuery object:
qry.RowLimit = 10;
When working with the GetListItems method of the Lists.asmx web service:
XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");
queryOptionsNode.InnerXml = "<RowLimit>10</RowLimit>";

IncludeMandatoryColumns

When this Boolean property is set to True, the result set will not only return the columns as defined in theViewFields property, but also the columns that you defined in the list as required.
When working with the SPQuery object:
qry.IncludeMandatoryColumns = true;
When working with the GetListItems method of the Lists.asmx web service:
XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");
queryOptionsNode.InnerXml =
    "<IncludeMandatoryColumns>True</IncludeMandatoryColumns>";

DatesInUtc

Setting this Boolean property specifies whether the query returns dates in Coordinated Universal Time (UTC) format. The syntax is similar to that of the previously described property.

ExpandUserField

When you omit this property or set it to false, user fields will return the login name of the user.
Setting this Boolean property to true  (or include it in the QueryOptions node), user fields are returned as follows:
Karine Bosch,#U2UCOURSE\karine,#karine@U2UCOURSE.COM,#,#Karine Bosch
The returned value includes the login name, e-mail address, Session Initiation Protocol (SIP) address, and title, when present, which causes a user field to behave as a multilookup field.  The syntax is similar to that of the previously described property.
There are some other query options to set but they will be explained in detail in the next section.

Special Types of Queries

Some special types of lists require more specialized CAML queries. In some cases it only affects the CAML but in other cases you have to set extra SPQuery properties. If you execute this query against the Listsweb service it will affect another argument of the GetListItems method, i.e. the QueryOptions argument.

Building queries for working with Folders

A first variant I will explain is how you can work with folders and sub folders. A folder is a special list item on a list or document library. If you execute a standard CAML query you will end up with list items from the root folder.
If you want to query all folders and sub folders of a list or document library, you have to define extra query options. If you are working with the object model you have to set the ViewAttributes property of theSPQuery object as follows:
qry.ViewAttributes = "Scope='Recursive'";
If you work with GetListItems method of the Lists.asmx SharePoint web service, you have to define an extra node with the QueryOptions element:
XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");
queryOptionsNode.InnerXml = "<ViewAttributes Scope=\"Recursive\" />";
If you want to query a specific sub folder using the SPQuery object, you have to set the Folder property:
qry.Folder = list.ParentWeb.GetFolder("Folders DocLib/2008");
When working with the web services you have to do the following:
XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");
queryOptionsNode.InnerXml = "<Folder>Folders DocLib/2008</Folder>";

Building Queries for working with DateTime Values

Filtering on DateTime fields also requires some extra attention. First of all when querying for a specific date, you have to use the SharePoint datetime notation:
<Where>
   <Ge>
        <FieldRef Name="StartDate" />
        <Value Type="DateTime">2008-08-10T10:00:00Z</Value>
   </Ge>
</Where>
But in this case the date is hard coded and the time part will not be taken into account. This query will return all list items with a start date as of 10 August 2008, also those starting before 10 o’clock. If you want your query to take into account the time part, you have to use a special attribute IncludeTimeValue that you can set on the FieldRef element:
<Where>
   <Ge>
        <FieldRef Name="StartDate" IncludeTimeValue="TRUE" />
        <Value Type="DateTime">2008-08-10T10:00:00Z</Value>
   </Ge>
</Where>
This query will return all list items with a start date as of 10 August 10 o’clock.
As already said, this way the date is hard coded. If you want your query a bit more dynamic, you can always use the element Today.
<Where>
   <Ge>
        <FieldRef Name="StartDate" />
        <Value Type="DateTime"><Today /></Value>
   </Ge>
</Where>
Today will not take a time part into account. Unfortunately a Now element doesn’t exist.
You can also add or subtract a number of days from today’s date. In that case you have to add the Offsetattribute to the Today element. The Offset attribute accepts a positive value for adding days and a negative value for subtracting days.
 <Where>
   <Ge>
        <FieldRef Name="StartDate" />
        <Value Type="DateTime"><Today Offset="10" /></Value>
   </Ge>
</Where>
As all this is pure CAML, the query is the same whether you work with the object model or the SharePoint web services.

Building Queries for Calendar Lists

Calendar lists also require a little more attention. A calendar list is based on the Event content type. Normal events can be retrieved with the usual CAML queries. It’s only when you start working with recurring events (events that occur once a day or twice a week or month) that you run into problems.
The Event content type defines a field named fRecurrence, which is set to 1 when a recurring event is created.
Defining a recurring event
Defining a recurring event
When the Calendar view is rendered a recurring event is split into a number of event instances, one for each recurrence.
Calendar view showing event instances for recurring event
Calendar view showing event instances for recurring event
The definition of the recurrence is XML stored in another field defined by the Event content type, i.e.RecurrenceData. An example of such a definition looks as follows:
<recurrence>
   <rule>
     <firstDayOfWeek>su</firstDayOfWeek>
     <repeat>
        <weekly mo="TRUE" we="TRUE" weekFrequency="1" />
     </repeat>
     <repeatForever>FALSE</repeatForever>
   </rule>
</recurrence>
Fortunately you don’t have to parse the XML yourself to get the actual instances of the recurring event. You can use a combination of CAML syntax and query options to achieve this.
When working with the SPQuery object you need to set the ExpandRecurrences property to true. You also have to specify a date in the CalendarDate property. This date will be used to compare the recurring event instances.
Next you have to add a DateRangesOverlap element to the Where clause of the CAML query. This element is used in queries to compare the dates in a recurring event with the date specified in theCalendarDateproperty to see whether they overlap. The CAML looks as follows:
<Where>
   <DateRangesOverlap>
      <FieldRef Name=\"EventDate\" />
      <FieldRef Name=\"EndDate\" />
      <FieldRef Name=\"RecurrenceID\" />
      <Value Type=\"DateTime\"><Month /></Value>
   </DateRangesOverlap>
</Where>
The <Month /> element is used to specify that all occurrences within a month need to be returned. You can also specify Day, Week or Year.
In case you need to work with the GetListItems method of the Lists.asmx web service, you translate the query options into XML:
XmlNode queryOptionsNode = camlDocument.CreateElement("QueryOptions");
queryOptionsNode.InnerXml = "<ExpandRecurrences>TRUE</ExpandRecurrences>"
 + "<CalendarDate>2008-08-12T10:00:00Z</CalendarDate>";
This is it about retrieving List Items using CAML. Don’t hesitate to post your comments and questions below.