In SharePoint 2010, you'll notice an area that was given great attention. It's now easier to work with SharePoint data in multiple scenarios. In SharePoint Foundation 2010 (SPF2010), Microsoft added LINQ support to help you create solutions that run on SharePoint servers. By introducing a RESTful service that exposes all lists and their contents, Microsoft also addressed the challenge of working with SharePoint data coming from external applications. Thankfully, Microsoft didn't stop there.
With every release of SharePoint, customers consistently requested new Web services. The latest release of SharePoint contains a vastly reworked user interface (UI) that dramatically reduces the number of page refreshes. Microsoft needed something new to satisfy its own demands for the improved UI and to provide a better and more robust platform for creating solutions that will run off SharePoint servers. This has been achieved with the client object model, which consists of three major components (.NET, Silverlight, and ECMAScript) that you can use in various situations.
The three implementations of the client object model share striking similarities. As I'll explain in this article, all three work the same way and have only subtle differences. The first question you might ask about the client object model is “What can or can’t I do with it?” Generally speaking, you can work and perform the most common actions on SharePoint site collections (e.g., reading and writing data on lists, creating lists, managing user permissions), as well as work with Web Parts on Web Part pages.
ClientContext: The Client Object Model Hub
All three client object models have a single center of gravity: the ClientContext object. The ClientContext object establishes a connection from the client to the remote SharePoint site, manages authentication, and handles the execution of code on the server queued by the client. Creating an instance of the ClientContext object is the first step in any client object model solution, as shown in Figure 1. Note that this object implements the IDisposable interface and thus should be wrapped up in a using() statement or disposed of properly. After you've created a ClientContext object, you can leverage its power to work with data in SharePoint lists and to use the provided support structures such as data CRUD operations, exception handling, conditional scopes, and authentication.
Data CRUD operations: Once a ClientContext object has been established with the server, the next thing you'll want to do is perform some sort of CRUD (create, read, update, or delete) operation on SharePoint lists.
As previously mentioned, the ClientContext object handles all communication between the client and the SharePoint site. This communication is done by queuing commands to run on the server and then executing them as a batch. This model gives you full control over how chatty your application will be with the server.
Grasping how the client object model talks to the server can be a bit confusing at first, but it's much easier to understand when compared to something most of you are familiar with: working with a SQL Server database. When programming against SQL Server, you first build the query, then you execute the query, and then you work with the results of the query.
The client object model works the same way. Before you can work with objects they must be initialized by using either the ClientContext.Load() or ClientContext.LoadQuery() method. The two methods work in very different ways. The .Load() method hydrates an object that is passed in. For instance, in Figure 2 the provided site collection is initialized when calling the .Load() method. This is like writing a SQL query. Before accessing any of the properties on the site collection the request must be sent to the server for processing by using the ClientContext.ExecuteQuery() method (or the ExecuteQueryAsync() method in the Silverlight and ECMAScript client object model).
A convenient aspect of the .Load() method is that you can specify exactly which properties you're interested in, resulting in a smaller result set and a more manageable object. You do this by using a Lambda expression, or series of Lambda expressions, to specify exactly which properties to hydrate on the passed in object, as shown in Figure 3.
The .Load() method is not the only option available for getting data from SharePoint. The other option, ClientContext.LoadQuery(), doesn't hydrate an object. Instead, it takes in a LINQ query and returns an IEnumerable collection, as shown in Figure 4. It's important to note that this LINQ query is not using LINQ to SharePoint; instead, it's using LINQ to objects.
Exception handling: The client object model introduces a new paradigm where not only will the code you’re writing execute on the client, but to a certain degree some work will be done on the server. What happens when an exception occurs in code that runs on the server? This exception is returned to the client and it's now the client’s responsibility to figure out what happened. If a lot of .Load() or .LoadQuery() methods were called before executing the batch using the .ExecuteQuery() method, and one of them throws an exception, isolating the root of the problem can be challenging.
To make things easier, Microsoft included an exception handling pattern that lets you build a try-catch-finally block and send it across to the server for processing. In this way, the exception can be caught and handled on the server before coming back to the client. You do this by using the ExceptionHandingScope object, as shown in Figure 5.
Conditional scope: As in standard development done on the server, coding conditions by relying on exceptions being thrown is not a great idea. Thankfully, the client object model gives you a way to execute code conditionally using the ConditionalScope object. When executing code on the server, this object lets you execute code provided a certain condition is met. The ConditionalScope object is available in both of the managed client object models but not in the ECMAScript client object model.
Authentication: The client object models have a default authentication built in. Both of the managed client object models authenticate using the default credentials of the authenticated user running the code. However, in the case of the .NET client object model, you can use the ClientContext.AuthenticationMode property to change the authentication to use anonymous or forms-based authentication.
Depending on the authentication mode specified, the client object model calls the SharePoint authentication Web service (http://\\[...\\]/_vti_bin/Authentication.asmx), then obtains and sets a cookie that it uses for future calls.
Changing the authentication mechanism is allowed only in the .NET client object model. The ECMAScript client object model uses the authentication of the page it's hosted within; it cannot change its authentication.
Implementing the Client Object Model
Before using the client object model, you need to know how an application must be configured to leverage the model. Although the three client object models share similarities, a few subtle differences exist in terms of limitations and implementations.
.NET client object model: The .NET client object model is designed for use in applications that will run off the SharePoint servers and connect to SharePoint remotely. This could include applications running on a laptop or integrated into a bigger system that needs to communicate with SharePoint. These applications can be either x86 or x64 and require the .NET Framework 3.5 SP1 or higher.
Custom .NET applications will need to add references to two assemblies in order to use the client object model. These two assemblies are found on the SharePoint server: c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI:
- Microsoft.SharePoint.Client.dll—contains the client object model.
- Microsoft.SharePoint.Client.Runtime.dll—handles all communication between the client and SharePoint server.
Copy these two assemblies to the developer machine and include them in the deployed project. Once you've added these two assemblies to the project, you can create a ClientContext object and start programming against the SharePoint Server.
One difference between this client object model and the other two implementations is that the .NET client object model offers only the synchronous ClientContext.ExecuteQuery() method. This means that, if your application needs to create asynchronous calls, you'll need to build it on your own. For example, in the case where a custom application's UI triggers a call to SharePoint via the client object model, you should employ good practices and move the data call to a background thread to keep the UI responsive.
You can work with background threads in various ways. One example is to use the Dispatcher in WPF applications. Figure 6 demonstrates retrieving the Title property of a site from SharePoint on a background thread. Once the call successfully completes, the Dispatcher is used to make the call back to the UI thread.
Silverlight client object model: The Silverlight client object model is similar to the .NET client object model in many ways; they both work with a managed API. To add the Silverlight client object model to a Silverlight project, add the two assembly references found in the c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin folder:
- Microsoft.SharePoint.Client.Silverlight.dll—contains the client object model.
- Microsoft.SharePoint.Client.Runtime.Silverlight.dll—handles all communication between the client and SharePoint server.
One difference between the .NET client object model and the Silverlight implementation is that all network calls in Silverlight applications are required to be asynchronous. Therefore, there is no synchronous execute method. The only available option is the ClientContext.ExecuteQueryAsync() method. Figure 7 demonstrates using the Silverlight client object model to perform the same task as in the .NET client object model code in Figure 6.
ECMAScript client object model: Implementation of the unmanaged ECMAScript client object model feels very different from the two managed client object models because of the syntax of working with objects in ECMAScript. The biggest differences between the ECMAScript client object model and the two managed client object models:
- The ECMAScript client object model’s ClientContext constructor takes zero parameters because it's locked to communicating only with the site the page is loaded from. This limitation prohibits cross-site scripting, a universally recognized security exploit.
- When writing back to SharePoint, the page that contains the ECMAScript should contain an instance of a FormDigest control to create a digest for security validation on the page.
The ECMAScript client object model has been written to not conflict with other script libraries, such as the popular jQuery and jQuery UI libraries. In fact, you can mix the use of the ECMAScript client object model and jQuery as much as you like to create robust script solutions.
To implement the ECMAScript client object model, add a single reference to the http://\\[..\\]/_layouts/sp.js file. This will add all dependent references to the page at load time. When you need to perform work with the ECMAScript client object model when the page loads, you need to make sure that the entire client object model is available and that it has been downloaded before running your code. In these cases, use the ExecuteOrDelayUntilScriptLoaded(function, library) method to call custom script functions that should be called only after the SharePoint ECMAScript library has been loaded. Figure 8 demonstrates using the ECMAScript client object model along with the popular jQuery library.
A New World
In this article, you were introduced to the three SharePoint 2010 client object models. I discussed the most important aspects and differences between each of the implementations.
You learned that you no longer have to create custom services to talk to SharePoint to satisfy your business needs. Instead, you can work with a rich API in custom .NET applications and Silverlight applications—or you can use ECMAScript for pure client-side creations.