SharePoint 2010: Client Object Model for JavaScript (ECMAScript)

As I said in my first post on Client Object Model (OM), there are three sets of Client OM: Managed .net client, Silverlight and ECMAScript. Lately I have posted an article on how to use Client OM from Managed .Net Client.Today I’ll go through Client OM for JavaScript.  ECMAScript Client OM is SharePoint 2010 client object model extension for using with JavaScript or JScript. Few points to notice about ECMAScript Client OM:
  • ECMAScript object model can only be used in SharePoint sites. So you can’t use this object model in an asp.net site to access SharePoint resources deployed in another url as this is cross-site scripting and not allowed.
  • You can’t use this object model in a SharePoint site to access resources in different SharePoint sites(i.e., different urls). For example, from mysite.mysp.com you can access resources in yoursite.yoursp.com using ECMAScript client OM. This is also cross-site scripting.
  • You can use JQuery with ECMAScript Client OM and for this you don’t need to do some extra work. All you need to do to use JQuery is to add reference to JQuery.js file and start using JQuery.
  • You can use this ECMAScript Client OM in web part pages or application pages (aspx pages) by referencing a javascript file (SP.js). You don’t need to add reference to the file manually rather use <SharePoint:ScriptLink Name=”sp.js” ………. />. The file is located on the path “Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS”
  • To update with JavaScript, you need to add a FormDigest tag in your page for security purpose. I’ll explain it later in details.

Use ECMAScript Library

At first use Visual Studio 2010 to create a SharePoint web part project. As a result, VS2010 will open a ascx control for you on the designer. 

1. Add reference to js file:

To use Client OM, add an entry like below in your web part ascx control. For your information, there’s an debug version of the sp.js called sp.debug.js which you can use for debugging but should not be used in production.
<SharePoint:ScriptLink Name="SP.js" runat="server" OnDemand="true" Localizable="false" />
Here, OnDemand means whether the sp.js file need to be loaded on demand (not in page load) or not.

2. Add FormDigest tag:

If your code modifies SharePoint content add a FormDigest control inside your page. The FormDigest add a security token inside your page based on user, site and time. Once the page is posted back the security token is validated. Once the security token is generated it’s valid for a configurable amount of time. Add the FormDigest inside <form>…</form> tag, as shown below:
<SharePoint:FormDigest runat="server" />
For more information on FormDigest follow the links below:

3. Use Client OM to retrieve data:

Now you can use SharePoint ECMAScript library. Lets dissect the code snippet below. The first thing in using this library is that you need to get the ClientContext (just like SPContext). Then the context.get_web returns the current web (just like SPContext.Current.Web). Then client context’s load method is invoked passing the web object. Then the executequery method is invoked asynchronously passing two functions: onSuccess and OnFailed which will be called on success and fail correspondingly.
<script type="text/javascript">
    function getWebProperties() {
        var ctx = new SP.ClientContext.get_current();
        this.web = ctx.get_web();
        ctx.load(this.web);
        ctx.executeQueryAsync(Function.createDelegate(this, this.onSuccess), Function.createDelegate(this, this.onFail));
    }
    function onSuccess(sender, args) {
        alert('web title:' + this.web.get_title() + '\n ID:' + this.web.get_id() + '\n Created Date:' + this.web.get_created());
    }
    function onFail(sender, args) {
        alert('failed to get list. Error:'+args.get_message());
    }
</script>
By calling getWebProperties method from any web part, you can get the current web’s title, id and creation date.

4. Load minimal data you need:

In the above code snippet, the Ctx.load method is invoked with only one parameter (web). The load method will load all properties of the web object. But we are only using Id, Title and Created Date properties. If you know which properties you are interested in, you can pass the properties names in the load method and only those properties will be loaded. For example the following load method will return only ID, Title and Created Date.
ctx.load(this.web,'Title','Id','Created');
Remember, here the properties names are properties of SPWeb. You need to pass Title instead of title. The properties name uses CAML casing. You can get the full lists of ECMAScript namespaces, object, properties following the link on MSDN. The document is not final yet and may be changed. You can also look into the sp.debug.js file in the folder “Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS”, to get an idea of objects, properties and methods of ECMAScript Client OM.

5. Execute your JavaScript function after sp.js is loaded:

Sometimes you may need to execute your JavaScript (that uses ECMAScript Client OM) on page load in the browser. But since your JavaScript is using sp.js file and if the sp.js file is not loaded yet (since to lazy loading nature of sp.js), when your custom JavaScript will be executing, you’ll get your JavaScript function not executed. In this case you need to make sure your JavaScript code runs after sp.js finishes loading. You can do so by putting your JavaScript method call inside a js function as shown below:
ExecuteOrDelayUntilScriptLoaded(myjsfucntion, "sp.js");
Putting your JavaScript function (i.e., myjsfunction) inside the ExecuteOrDelyUntilScriptLoaded method delays your method call until the sp.js file is loaded.

6. Update with ECMAScript Library:

You can use the Client OM to update SharePoint contents. The following code snippet shows how to update web title.
<script type="text/javascript">
    function updateTitle() {
        var ctx = new SP.ClientContext.get_current();
        this.web = ctx.get_web();
        web.set_title('UpdatedTitle');
        this.web.update();
        ctx.executeQueryAsync(Function.createDelegate(this, this.onUpdate), Function.createDelegate(this, this.onFail));
    }
    function onUpdate(sender, args) {
        alert('title updated');
    }
    function onFail(sender, args) {
        alert('failed to update title. Error:'+args.get_message());
    }
</script>
By calling the updateTitle method from any web part or SharePoint application pages, you can change the title of current web site (where the web part or application page is deployed). For your information, in ECMAScript Client OM, to get an property use get_propertyName and to set a property use set_propertyName. To update list with ECMAScript library you need to add FormDigest tag.

Use JQuery with ECMAScript

You can use JQuery with ECMAScript without any conflict. As usual, you need to add jquery.js file reference to your page/web part or in master page. Then you can use JQuery as like normal asp.net applications. But make sure that if you need to execute any JavaScript function on page load event, you put this inside ExecuteOrDelayUntilScriptLoaded function.

Deployment Consideration

SharePoint provides two sets of JavaScript file: minified and unminified/debug version. For example sp.js file is minified and sp.debug is minified and debug version. The default master page in SharePoint has a scriptmanager in the page and whose ScriptMode is set to auto, as a result the minified version of js file loaded. If you want to use debug version you can add the <deployment retail=”false” /> in the <system.web> section of the web.config. In the production you need to remove this entry to make sure minified version is used. The ECMAScript supported in the following browsers:
  • Microsoft Internet Explorer 7.0 or greater.
  • Firefox 3.5 or greater
  • Safari 4.0 or greater

More Information

To get the full list of namespaces and Classes, you can download the SharePoint 2010 SDK or you can follow the link on MSDN.

SharePoint 2010 Deployment: Powershell Script

Pre-SharePoint 2010 developers are familiar with Stsadm command. The general scenario of SharePoint 2007 deployment is to develop a batch file with stsamd commands. A generic deployment includes the following steps:
  • Deactivate Features
  • Uninstall Features
  • Retract Solution
  • Delete Solution
  • Add Solution
  • Deploy Solution
  • Install Features
  • Activate Features

SharePoint 2007 Deployment Script:

I’ll first describe how stsadm command file looks like implementing the above steps. You can put the following script in a batch file and then clicking on the batch file in SharePoint server, will deploy the solution. The solution and the batch file need  to be in the same folder. The first line of the script (cd /d %~dp0) will change the current directory to the script directory.
--Change script directory to current directory 
cd /d %~dp0 
@SET STSADM="c:\program files\common files\microsoft shared\web server extensions\12\bin\stsadm" 
@SET SITEURL="http://localhost" 

echo Deativating 'MyFeature' feature. 
%stsadm% -o deactivatefeature -name MyFeature -url %SITEURL% -force  
echo Uninstalling 'MyFeature' feature. 
%stsadm% -o uninstallfeature -name MyFeature -force  

echo Retracting solution 'MySolution.wsp' 
%stsadm% -o retractsolution -name MySolution.wsp -immediate -allcontenturls %stsadm% -o execadmsvcjobs  
echo deleting solution 'MySolution.wsp' 
%stsadm% -o deletesolution -name MySolution.wsp -override  

echo adding solution 'MySolution.wsp'
%stsadm% -o addsolution -filename MySolution.wsp  
echo deploying solution 'MySolution.wsp' 
%stsadm% -o deploysolution -name MySolution.wsp -url %SITEURL% -immediate -allowGacDeployment -force 
%stsadm% -o execadmsvcjobs 

echo Installing 'MyFeature' feature. 
%stsadm% -o installfeature -name MyFeature -force  
echo activating 'MyFeature' feature. 
%stsadm% -o activatefeature -name MyFeature -url %SITEURL% -force  
iisreset /restart /noforce /timeout:60
File: SharePoint 2007 Script for Deployment
 

PowerShell Scripting Basic, every SharePoint Developer Should Know

In SharePoint 2010 stsadm is supported but powershell commands are recommended to use. To know how to run SharePoint powershell script, let’s get an overview of PowerShell. I’ll try to provide a gist on Powershell so that you can write your own Script for SharePoint. As as SharePoint developer we don’t need to be expert in PowerShell script but we need to know the basic syntax.
 PowerShell command format: Powershell command has two parts: verb and noun. For example, to get current date, you need to execute command get-date. Here get is verb then a hyphen(-) and finally date which is noun. Powershell is not case sensitive. But its good practice to use Caml case in command. The following command uses verb-noun format to get current date.
Get-Date 
Get Help on PowerShell Command: To get help for a command you can use Get-Help command. The following command is used to get help on Get-Date:
Get-Help Get-Date
You can even type the verb part including hyphen and then press tab. You’ll then get the all commands starting with the verb.
PowerShell command execution Permission: Before you execute any command, you need to enable PowerShell to execute command. You can get the current execution policy by running the following command:
Get-ExecutionPolicy
The result of the command might be one of the followings:
  • Restricted
  • AllSigned
  • RemoteSigned
  • Unrestricted
  • Bypass
  • Undefined
To execute command or run scripts, you can set execution policy to ReomteSigned but based on your security consideration, you can use different options. To set execution policy, you can run the following command:
Set-ExecutionPolicy RemoteSigned
Run a PowerShell Script: To run a PowerShell script, you need put the file name in the PowerShell command prompt. But there are few conventions/restrictions that you need to follow.
  • To run a script file you need to type complete path of the script file. The complete path may be in the form ‘.\folder\subfolder\script.ps1’ or a full path like ‘c:\folder\subfolder\script.ps1’
  • To execute a script you need to use the format of & ScriptPathformat. If the file path has space then use double quotation to enclose the path. So to execute a file you can use the command like below:
& “C:\My Scripts\Script.ps1”
  • If you want to run PowerShell script from Run window then you can do so by putting the following command in Run window:
Powershell –NoExit & ‘C:\My Scripts\Scripts.ps1’
One thing to remember in the above script is that single quote is used instead of double quote when you will run the above command from Run window. Single quote must be used for file path if the file path has space. Double quote will not work in this case.
  • Variables in PowerShell are identified by putting a  $ prefix. You’ll find how the variable is used in the section “A Sample PowerShell Script”
  • PowerShell script file is saved with extension .ps1
A Sample PowerShell Script:
Let’s say you have a PowerShell script (as shown below) in a file named script.ps1. Now You want to run the following powershell script (in a file Script.ps1) from Run window. The script will add two numbers and print the output.
echo 'setting a value for a'
$a=5
echo 'setting a value for a'
$b=3
echo 'adding a and b'
$c=$a+$b
echo "reslut is $c"
 

The variables in the above script are prefixed by $. Take a close look at the last echo. The echo has a $c in the double quotation. Remember, you can refer a variable name in double quotation string (as in the last echo in the above script). But the same is not true for single quote. If you would use the $c inside single quote then it would print back the $c. Single quote is considered as literal string in PowerShell.

SharePoint 2010 Deployment

In SharePoint 2010, you can use PowerShell script for deploying SharePoint solution/features. Let’s first take a look at how the deployment script will look like
PowerShell Deployment Script: Deployment in SharePoint 2010 still has the same eight steps (Deactivate Features, Uninstall Features…..) as described at the beginning of this post. The following script deploy a solution:
function WaitForJobToFinish([string]$SolutionFileName)
{ 
    $JobName = "*solution-deployment*$SolutionFileName*"
    $job = Get-SPTimerJob | ?{ $_.Name -like $JobName }
    if ($job -eq $null) 
    {
        Write-Host 'Timer job not found'
    }
    else
    {
        $JobFullName = $job.Name
        Write-Host -NoNewLine "Waiting to finish job $JobFullName"

        while ((Get-SPTimerJob $JobFullName) -ne $null) 
        {
            Write-Host -NoNewLine .
            Start-Sleep -Seconds 2
        }
        Write-Host  "Finished waiting for job.."
    }
}

Add-PsSnapin Microsoft.SharePoint.PowerShell

$CurrentDir=$args[0]
$solutionName="Limeco.UI.WebParts.wsp"
$SolutionPath=$CurrentDir + "\"+$solutionName 

Write-Host 'Going to disable feature'
disable-spfeature -identity Limeco.UI.WebParts_LimecoWebPartFeature -confirm:$false -url http://localhost

Write-Host 'Going to uninstall feature'
uninstall-spfeature -identity Limeco.UI.WebParts_LimecoWebPartFeature -confirm:$false -force

Write-Host 'Going to uninstall solution'
Uninstall-SPSolution -identity $solutionName  -allwebapplications -confirm:$false

Write-Host 'Waiting for job to finish'
WaitForJobToFinish 

Write-Host 'Going to remove solution'
Remove-SPSolution –entity $solutionName -confirm:$false

Write-Host 'Going to add solution'
Add-SPSolution $SolutionPath

Write-Host 'Going to install solution to all web applications'
Install-SPSolution –entity $solutionName –llwebapplications –ACDeployment

Write-Host 'Waiting for job to finish' 
WaitForJobToFinish 

Write-Host 'Going to enable Feature' 
Enable-spfeature -identity Limeco.UI.WebParts_LimecoWebPartFeature -confirm:$false -url http://localhost 

Remove-PsSnapin Microsoft.SharePoint.PowerShell
File: Myscript.ps1
 
The first thing in the above script is a function WaitForJobToFinish which is used to make sure jobs are finished executing before moving on. This method is similar like the command ‘stsadm –o execadmsvcjobs’ in SharePoint 2007. In the above script, the line ‘Add-PSSnapin’load the SharePoint PowerShell script. If you already using SharePoint 2010 Management Shell (Which is a PowerShell extension already) then this line should be removed. In the above script Write-Host is just like print function that print a string in the console. FYI, when you pass arguments to an PowerShell script, the arguments are kept in a PowerShell variable $Args. You can access any arguments by assessing it $Args[index]. I think the command in the above script is self-explanatory. The –confirm:$false is for not to prompt user for confirmation. In the above script you need to pass the solution directory.
 
Automate the Deployment Script: To automate the powershell Script you need to put the above script in a PowerShell scipt file(having ps1 extension). Let’s say you have you script in a file named as myscript.ps1. Now you need to run the script you need a batch file which will execute the script file. The script file may be like one shown below:
cd /d %~dp0
powershell -noexit -file    ".\MyScript.ps1" "%CD%"
 File: MyCommand.bat
 
In the above command, the first line change the current directory to the location from where the batch file is run. Then I have run the PowerShell with the MyScript.ps1 file and passed the current directory as argument (%CD%)

Conclusion

I think stsadm command was simple and easy to use. PowerShell is too much powerful and extensible. You can do almost all kinds of SharePoint programming with PowerShell script. My personal view is that we, SharePoint developers, don’t need to be expert in PowerShell but we need to have basic knowledge of “How to use PowerShell Script for SharePoint Deployment/Maintenance?”. There are already much activities on web around PowerShell and SharePoint. Few useful links related to PowerShell and SharePoint are given below:
Some Useful CodePlex links:
Here is a Visual Studio 2010 extension for SharePoint PowerShell Scripting:
Here is a tool called PowerGui that is handy for editing PowerShell script:

 
The concept for waiting for job to finish, I have taken from the following link:

SharePoint 2010: Add button to Ribbon with SharePoint designer



Sometimes you may need to add buttons to SharePoint 2010 ribbon. You can take one of two approaches: You can write code to add the button. Another approach is to use SharePoint Designer to add button to Ribbon. Today I’ll show you how to add button to Ribbon using SharePoint Designer. However, when you’ll use SharePoint Designer to add button to Ribbon and if you do  so in Development or Staging server, then think about how to do the same in Production server.

Add Button to List/Library forms (AllItems.aspx, DispForm.aspx, EditForm.aspx, NewForm.aspx)

Let’s say you have a list and you want to add a new Ribbon button in the AllItems.aspx page.
1. First open the site in SharePoint Designer.
2. Then click “List and Libraries” link from the left-hand menu and then click the target list from the details page on the right hand side as shown below:
image
Figure 1: Select List/Libraries in SharePoint Designer

3. Once you click the list name you’ll be landed to the list/library settings page. In this page you can edit four forms (AllItems.aspx, DispForm.aspx, EditForm.aspx and NewForm.aspx) and you can add button to the page’s ribbon. The page is shown below:
image 
Figure 2: Four built-in Forms

4. From the ‘List Settings’ tab on the top, select ‘Custom Action’ as shown below:
image
Figure 3: Add custom Action

5. Say you want to add button to ‘NewFom.aspx’. For this click ‘New Form Ribbon’ from the Custom Action. You’ll get the ‘Create Custom Action’ window where you can add custom action to the Ribbon. From the window below you can chose one of three different actions: Navigate to form, Initiate workflow, Navigate to Url. If you need more custom action then SharePoint Designer will not be helpful. You need to write code to extend Ribbon button actions.
image
Figure 4: Custom Action Properties



Find Ribbon Location:

In the List/Library form, the button are placed in groups. As shown in the image below, the new form has three sections:
image
Figure 5: Buttons are placed in Groups/Sections in form
Now you may want to place your button in a particular group and for that you need know the location id so that you can put the id in the ‘Ribbon Location’ in the custom action properties in SharePoint Designer. Using Firebug extension of Mozilla Firefox, I have found the ribbon location id as shown below:
image
Figure 6: Ribbon group/section id (detected using Firebug extension of Firefox)
So now you can put the ribbon location id in the custom action properties. For example to put the ‘Show Me’ button in the ‘Commit’ section I have put the ribbon button location to ‘Ribbon.ListForm.Edit.Commit.Controls._children’. Here the ‘.Controls._children’ is added to the ribbon id. The following figure show two windows side by side:
image
Figure 7: Custom Action windows (On Left) and New Item Form (On right) with ‘Show Me’ button


Decide when to show the Ribbon Button

Sometimes you don’t want to show the button for all users. Rather you want to show for users having a set of permissions. The ‘Rights mask’ option allow us to meet this requirements. The available values can be foundon MSDN. You can put more than one values in the Rights Mask text box separated by semicolons as shown below:
image
Figure 8: Rights mask







Define Ribbon button sequence in a group

You can determine the ribbon button location in a group/section by setting the ‘sequence number’. I have not found documentation about the sequence number but I have found by myself that each position holds 10. So giving 10 in that filed will show as the first button. Putting any value more than 10 but less than 20 will show as second button and so on.

CAML and the Client Object Model

SharePoint 2010 comes with a whole set of new features. One of these novelties is the Client Object Model. (Well it are 3 novelties because there are 3 different Client Object Models that you can use depending on the situation you are in).
When SharePoint 2010 came out, there were some rumours that CAML was dead because now we have LINQ to SharePoint. But these rumors are not true: CAML is still there and is still very important for the performance of your SharePoint application. In this blog post I’m going to detail how CAML can be used with the .NET Client Object Model.

Working with the .NET Client Object Model

Before you can start working with the .NET Client Object Model, you have to add a reference to the assemblies Microsoft.SharePoint.Client.dll and Microsoft.SharePoint.Client.Runtime.dll. You can find these assemblies in the 14\ISAPI folder.

The Where clause

The Where clause can range from very simple to very complex with one or more nested <And> or <Or> elements. The CAML for the Where clause has not been changed since SharePoint 2003, and can be used with the SharePoint Server Object Model and with the three Client Object Models. Also the Web Services are still there, for which you can also use CAML to retrieve and/or update list items.
To retrieve list items from a SharePoint list, you have to define an instance of type CamlQuery, defined within the Microsoft.SharePoint.Client.CamlQuery namespace. You can specify your CAML query within the ViewXml property. This property is of type string but its content must be XML. The root element for this property is <View>. The Where clause needs to be embedded within a <Query> element.
Microsoft.SharePoint.Client.CamlQuery query = new Microsoft.SharePoint.Client.CamlQuery();
query.ViewXml = "<View>"
   + "<Query>"
   + "<Where><Eq><FieldRef Name='Country' /><Value Type='Text'>Belgium</Value></Eq></Where>"
   + "</Query>"
   + "</View>";
// execute the query
ListItemCollection listItems = spList.GetItems(query);
clientContext.Load(listItems);
clientContext.ExecuteQuery();

OrderBy

The OrderBy element is the most simple one: you can define a sort order using one or more <FieldRef> elements that you include in the ViewXmlproperty of the CamlQuery object:
query.ViewXml = "<View>"
   + "<Query>"
   + "<Where><Eq><FieldRef Name='Country' /><Value Type='Text'>Belgium</Value></Eq></Where>"
   + "<OrderBy><FieldRef Name='City'/></OrderBy>"
   + "</Query>"
   + "</View>";

ViewFields

You can also limit the number of columns returned to the client, using the good old ViewFields element, which you can also include in the ViewXmlproperty of the CamlQuery object:
CamlQuery query = new CamlQuery();
query.ViewXml = "<View>"  
   + "<Query>"
   + "<Where><Eq><FieldRef Name='Country' /><Value Type='Text'>Belgium</Value></Eq></Where>"
   + "</Query>"
   + "<ViewFields>"
   + "  <FieldRef Name='Title' /><FieldRef Name='City' />"
   + "</ViewFields>"
   + "</View>";
// execute the query
ListItemCollection listItems = spList.GetItems(query);
clientContext.Load(listItems);
clientContext.ExecuteQuery();
But this also returns a number of system columns. If you really want to limit the columns returned to the columns you specify, you have to use a LINQ query within the Load method. The code looks as follows:
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = "<View><Where><Eq><FieldRef Name='Country' /><Value Type='Text'>Belgium</Value></Eq></Where></View>";
ListItemCollection listItems = spList.GetItems(camlQuery);
clientContext.Load(listItems,
      items => items.Include(
      item => item.Id,
      item => item.DisplayName,
      item => item.HasUniqueRoleAssignments));
clientContext.ExecuteQuery();

Query Options

The different Query Options need to be handled a bit differently than with the SharePoint Server Object Model.
The row limit can also be specified within the ViewXml property:
query.ViewXml = "<View>"
   + "<Query>"
   + "<Where><Eq><FieldRef Name='Country' /><Value Type='Text'>Belgium</Value></Eq></Where>"
   + "<OrderBy><FieldRef Name='City'/></OrderBy>"
   + "</Query>"
   + "<RowLimit>5</RowLimit>"
   + "</View>";
Dates in UTC
You can choose to return dates in UTC (Coordinated Universal Time)  by setting the DatesInUtc property of the CamlQuery instance:
query.DatesInUtc = true;
Include attachment URLs
Using CAML you are able to know if list items have attachment by adding a w> element to the ViewFields element in the ViewXml property:
query.ViewXml = "<View>"  
   + "<ViewFields>"
   + "  <FieldRef Name='Title' /><FieldRef Name='City' /><FieldRef Name='Attachments' />"
   + "</ViewFields>"
   + "</View>";
 SharePoint will return a boolean indicating whether the list item has attachments or not.
The attechments are not stored in the list item itself, but are stored in a sub folder of the list. More specifically, the list contains a folder named Attachments and if a list item has one or more attachments, a folder is created based on the ID of the list item. This sub folder will then contain the attachment(s). The URL of the attachment is not stored in the list item itself.
CAML contains an option IncludeAttachmentURLs that can be used to retreive the URL of the attachment(s), together with the other properties of the list item. It works on the server side SPQuery and with the <QueryOptions> node of the GetListItems method of the Lists.asmx web service , but it doesn’t seem to be available with the CamlQuery object of the .NET Client Object Model.
If you need to retrieving the attachments itself you will have to write some extra code that retrieves the files from the Attachment folder:
Folder folder = clientContext.Web.GetFolderByServerRelativeUrl(
    spList.RootFolder.ServerRelativeUrl + "/Attachments/" + item.Id);    
FileCollection files = attFolder.Files;    
// If you only need the URLs    
ctx.Load(files, fs => fs.Include(f => f.ServerRelativeUrl));    
ctx.ExecuteQuery();
Limitations
Following CAML subtilities doesn’t seem to be working with the CamlQuery object of the .NET Client Object Model, although they exist when retrieving list items with the server object model and the SharePoint web services:
  • IncludeMandatoryColumns: this option also returns the required fields besides the other fields specified in the ViewFields property or element.
  • ExpandUserField: when you query a User field, you only see the login name of the user. When you indicate that you want to expand a user field, SharePoint will also return information like the user name and the email address.
  • IncludeAttachmentURLs: cfr. higher
  • IncludeAttachmentVersion:
Files and folders options
CAML for retrieving files and folders at different levels of a document library, is always a bit more complex. To make the explanation hereunder a bit more readable, I have created a document library with the following structure:
You can easily query the files and folders in the root folder of a document library without having to use specific CAML elements. Only if you want to start querying the folder structure within a document library, you have to apply specific CAML.
To be able to better demonstrate the subtilities I created a folder structure in my Shared Documents library, and added a set of files to the different folders. (Needless to say that SharePoint Manager 2010 provided me this insight in my document library :) ).
For example, if you want to query all files and folders in your document library, no matter how deep they are nested,  you have to add a Scopeattribute to the View element, and set its value to RecursiveAll:
query.ViewXml = "<View Scope='RecursiveAll'></View>";
You can always add a Query element in the View element and specify a Where clause to add an extra filter to the query, or an OrderBy clause to sort the result.
If you want to query only the folders, you have to add an extra where clause:
query.ViewXml = "<View Scope='RecursiveAll'>"
   + "<Query>"
   + "   <Where>"
   + "      <Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>1</Value></Eq>"
   + "   </Where>"
   + "</Query>"
   + "</View>";
If you want to query only the files, the extra where clause can be changed as follows:
query.ViewXml = "<View Scope='RecursiveAll'>"
   + "<Query>"
   + "   <Where>"
   + "      <Eq><FieldRef Name='FSObjType' /><Value Type='Integer'>0</Value></Eq>"
   + "   </Where>"
   + "</Query>"
   + "</View>";
If you want to retrieve the content of a specific folder, i.e files and folders, you have to add the relative URL to that folder to the FolderServerRelativeUrl property of the query instance:
query.FolderServerRelativeUrl = "/Shared Documents/Folder 1";
If you only want to see the files of a specific sub folder, you have to set theScope attribute of the ViewXml property to FilesOnly:
query.ViewXml = "<View Scope='FilesOnly' />";
query.FolderServerRelativeUrl = "/Shared Documents/Folder 1";
Of course you can also query all files in a specific sub folder and its underlying sub folders. In that case you also have to specify the relative URL to the folder, but you also have to set the Scope attribute of the ViewXmlproperty to Recursive:
query.ViewXml = "<View Scope='Recursive' />";
query.FolderServerRelativeUrl = "/Shared Documents/Folder 1";
If you want to retrieve all files AND folders from a specific folder and its underlying sub folders, you have to set the Scope attribute of the ViewXmlproperty to RecursiveAll
query.ViewXml = "<View Scope='RecursiveAll' />";
query.FolderServerRelativeUrl = "/Shared Documents/Folder 1";