In SharePoint 2010 Microsoft
provided a version of the managed code CSOM for developers of .NET
applications. This library has been rebuilt for SharePoint 2013 and is
provided as part of the SharePoint installation. As in the 2010
release, it is provided as part of a redistributable package for
developers to include in their applications.
It is made up of the following .NET assemblies:
- Microsoft.SharePoint.Client.Runtime.dll
- Microsoft.SharePoint.Client.dll
- Microsoft.SharePoint.Client.DocumentManagement.dll
- Microsoft.SharePoint.Client.Publishing.dll
- Microsoft.SharePoint.Client.Taxonomy.dll
- Microsoft.SharePoint.Client.UserProfiles.dll
- Microsoft.SharePoint.WorkflowServices.Client.dll
Setup
Additionally you can find them in the following location on a machine with SharePoint installed, as shown in Figure 1:
%ProgramFiles%\Common Files\Microsoft Shared\web server extensions\15\ISAPI
After you have added references to these DLLs
from your .NET application such as a Windows Forms application or
console application, you can add a using statement as follows:
using Microsoft.SharePoint.Client;
In managed code one of the first things you must do to make calls to SharePoint is to establish a ClientContext.
It sets up things such as the URL to your SharePoint site and the
authentication details needed to communicate with the services. You can
instantiate a ClientContext object along with the URL of your site as shown here:
ClientContext context = new ClientContext("http://MySharePointSite");
After you have established a ClientContext
the next thing most people want to know is how to interact with
SharePoint data. The core set of SharePoint data objects in the CSOM
are as follows:
If you are familiar with the SharePoint
Server-Side Object Model these items will all sound familiar. However,
the naming convention is slightly different, and in the CSOM the “SP”
on the front is omitted. However, they map one to one with their
server-side equivalent.
In an installation where your SharePoint Server
uses Windows Authentication (NTLM) to secure it, the CSOM passes the
authentication context of the application process along with it. For
example, if you ran your console application under your account the
CSOM would be running as you are making the calls to SharePoint. This
means you would need to have the correct privileges in SharePoint for
the operations or data you were trying to access or you would receive
an access denied exception. So, for example, if you were trying to
manipulate ListItem object data with the CSOM you would need the
corresponding security privileges on those list items in SharePoint.
Querying
The CSOM has been built from the ground up with two important features in mind:
- Batching
- Returning only the data that you need
When you work with remote systems and call them
over potentially latent and unknown bandwidth connections, these two
things are very important. You must be able to keep the number of calls
and responses to a minimum and you should only bring back the minimum
amount of data you need to do your job. For this reason the CSOM only
executes calls when you ask it to and includes all statements and
operations since the last time you made it execute. This might at times
seem cumbersome to someone new to using the CSOM; however, it enforces
the developer’s involvement in these choices and ultimately helps make
better performing code.
The core object required to work with almost
every aspect of the CSOM is a Site or Web object. Because all
SharePoint data is stored in sites these objects are usually the first
ones you need to instantiate.
You can do it by querying the context for the Site and Web objects corresponding to the URL with which you constructed the ClientContext. You do this with the .Site and .Web properties like so:
ClientContext clientContext = new ClientContext("http://MySharePointSiteUrl");
Site site = clientContext.Site;
Web web = clientContext.Web;
Once you have your Site and Web context objects
you are ready to start working with data in them. As mentioned
previously the CSOM only brings back the data you ask it to. You use
the Load method on the ClientContext to do this as follows:
List list = web.Lists.GetByTitle("Movies");
ListItemCollection listItems = list.GetItems(CamlQuery.CreateAllItemsQuery(50));
clientContext.Load(listItems, items => items.Include(item => item["Title"]));
clientContext.ExecuteQuery();
In the Load statement the Include command instructs the CSOM to include that property in the results. In the example this instructs the CSOM to load the Title
property. Now you are ready to execute the operation against the
SharePoint Server. Remember, the CSOM only sends commands to SharePoint
when you are ready. Calling Load does not do that. The transaction only executes when you call the ExecuteQuery method, like this:
ClientContext clientContext = new ClientContext("http://MySharePointSiteUrl");
Web web = clientContext.Web;
clientContext.Load(web);
clientContext.ExecuteQuery(); // this line executes the instructions
By making the developer explicitly request that
the instructions be carried out, the CSOM enables you to batch your
commands into appropriate sets and thus minimize the number of requests
and responses to and from the server. On a highly latent connection
this can save many seconds of transmission time and thus help keep your
application speedy.
NOTE : If you attempt to use a property on a CSOM object and get a PropertyOrFieldNotInitializedException you likely have not asked for it to be returned and loaded by specifying it in a Load command.
This same technique is applicable in other
scenarios and operations, such as bringing back only the properties you
desire; for example:
ClientContext clientContext = new ClientContext("http://MySharePointSiteUrl");
Web web = clientContext.Web;
clientContext.Load(web, w => w.Title, w => w.Description);
clientContext.ExecuteQuery();
Here the Load
method is called, passing along a description of the properties to
return. If you don’t specify these properties only the default ones
will be returned.
The CSOM also allows for operations such as
creating data. Because you don’t have a reference to an existing
object, the CSOM instead uses a creation information object such as ListItemCreationInformation to capture all the information, such as the column data, about the ListItem.
The following example shows a basic use of the ListItemCreationInformation class to insert a new row into a list:
ClientContext clientContext = new ClientContext("http://MySharePointSiteUrl");
Web web = clientContext.Web;
List list = web.Lists. GetByTitle("Tasks")
clientContext.Load(web);
clientContext.Load(list);
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem listItem = list.AddItem(itemCreateInfo);
listItem["Title"] = "New Announcement!";
listItem.Update();
clientContext.ExecuteQuery();
Some other examples of creation information classes include:
- ListCreationInformation
- WebCreationInformation
- ViewCreationInformation
- FileCreationInformation
To try a practical example of using the CSOM in a console application, work through the following exercise.
My First CSOM Console App (MyFirstCSOMConsole.zip)
In this exercise you create a console
application that uses the Managed .NET CSOM to talk remotely to a
SharePoint on-premises server. You need a SharePoint 2013 site, Visual
Studio 2010 or 2012, and the SharePoint Client Components SDK
installed.
1. In your
SharePoint site create a new Custom list called Movies by clicking in
Site Contents ⇒ Add App, then pick Custom List from the list and call
it Movies. Click Create.
2. Click on the List tab of the ribbon and choose Create Column.
3. Select Number and call the column Length. Click OK to create the new column.
4. Add three or four new list items to the list for your favorite movies along with their lengths.
5. Open Visual Studio and create a new project by choosing Visual C# ⇒ Windows ⇒ Console Application project. Call it MyFirstCSOMConsole. Click OK to create the project.
6. Right-click References, then choose Add Reference.
7. Click Browse and browse to the %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\15\ISAPI folder.
8. Select Microsoft.SharePoint.Client.Runtime.dll and Microsoft.SharePoint.Client.dll. Click Add.
9. At the top of your Program.cs file add using Microsoft.SharePoint.Client;.
10. In the
Main()
function of your app add the following code. This code queries your
SharePoint site for its Title and queries the Movies list for its
items, only bringing back the ID, Title, and Length fields. You need to
replace
servername and
sitename with your own SharePoint Server details.
ClientContext clientContext = new ClientContext("http://servername/sitename");
Site site = clientContext.Site;
Web web = clientContext.Web;
clientContext.Load(web, w => w.Title);
List list = web.Lists.GetByTitle("Movies");
ListItemCollection listItems = list.GetItems(CamlQuery.CreateAllItemsQuery(50));
clientContext.Load(listItems, items => items.Include(item => item["Title"],
item => item["Length"], item => item.Id));
clientContext.ExecuteQuery();
Console.WriteLine(web.Title);
foreach (ListItem item in listItems)
{
Console.WriteLine(string.Format("Item: {0}, {1}, {2}", item.Id,
item["Title"], item["Length"]));
}
ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
ListItem listItem = list.AddItem(itemCreateInfo);
listItem["Title"] = "Diamonds Are Forever";
listItem["Length"] = 120;
listItem.Update();
clientContext.Load(listItems, items => items.Include(item => item["Title"],
item => item["Length"], item => item.Id));
clientContext.ExecuteQuery();
Console.WriteLine("Added Movie: " + listItem["Title"]);
11. Press F5
to run your console application. The Title of your site appears
followed by a row for each movie in the Movies list. Finally, you can
also see that your new ListItem was added to the list. Figure 2 outlines what you should see in the console window.
How It Works
In this exercise you created a console
application that used the Managed .NET CSOM to query your SharePoint
Server. You limited the data you received back by indicating in the Load statements just the properties you wanted and only executed the calls when ready with the ExecuteQuery statement.
Behind the scenes the CSOM is constructing queries to the SharePoint Server with XML and sending them to the _vti_bin/Client.svc
CSOM endpoint. SharePoint is then interpreting the calls and returning
the results in a JSON payload that the CSOM then unpacks into the
resultant CSOM objects.