This is the third post in a series of blog posts on the SharePoint app model. Here is the outline of this series.
If you haven’t read the previous posts in the series, you should consider reading them before continuing with this post. These earlier posts explain the basic architecture and the differences between SharePoint-hosted apps and cloud-hosted apps and discuss the role of the app web. This post assumes you already understand these concepts.
Getting Started with CSOM and the REST API
SharePoint apps cannot run any server-side code inside the SharePoint host environment. Therefore, they cannot use the SharePoint server-side object model. Instead, a SharePoint app must call from across the network to communicate with the SharePoint host environment. The two options that you have to accomplish this are using the client-side object model (CSOM) and issuing Web service calls based on the new SharePoint 2013 REST API.
As you recall, a SharePoint app can contain two fundamental types of code. First, a SharePoint app can contain client-side code that runs in the browser which is most often written in JavaScript. Secondly, a SharePoint app can contain server-side code that runs in the remote web associated with the app. In this post I will demonstrate writing this type of server-side code in C# although you can alternatively write it in VB or a plethora of other languages as well.
When you are designing a SharePoint app that must communicate with the SharePoint host environment, you must make two choices. First, you must decide whether to use client-side code or server-side code. Second, you must decide between CSOM and the REST API. This means there are four permutations for writing code in a SharePoint app that programs against a SharePoint site.
- Client-side JavaScript that uses CSOM
- Client-side JavaScript that uses the REST API
- Server-side C# code that uses CSOM
- Server-side C# code that uses the REST API
As you begin to consider whether to use CSOM or the REST API, you'll find that there is a good deal of overlap between them. Therefore, you will encounter scenarios where you could choose either one to accomplish the same goal. As a basic rule of thumb when getting started, you will find that CSOM is easier to use when programming in a managed language such as C#. You might also find that the REST API is easier to use when writing client-side JavaScript code especially when you are using today's most popular JavaScript libraries such as jQuery. However, there are still occasions where it is beneficial or necessary to write client-side code using CSOM or server-side code against the REST API.
My goal in writing this blog post is to get you started programming with each of these four programming styles listed above. However, I don't want to introduce too many topics at once so I will attempt to introduce the important concepts of CSOM and the REST API in isolation from other related topics. In this post I will avoid any detailed discussion of app authentication or app permissions. While these topics are essential in SharePoint app development, I think it's best to defer introducing them until later blog posts in this series.
In this post I will demonstrate using CSOM and the REST API by programming against the app web associated with a SharePoint app. My reason for doing this is that a SharePoint app by default has full permissions on its app web. Therefore, this scenario eliminates the need to deal with explicit app permission requests. I will revisit this topic in a later post in this series and provide you with the details you need to program against the host web which will require you to modify an app with explicit permission requests.
When I discuss writing server-side code in a cloud-hosted app in this post, I will concentrate on a scenario which involves internal authentication instead of external authentication. A scenario which involves internal authentication doesn't require explicit code to manage authentication. This will allow me to focus exclusively on the fundamentals of using CSOM and the REST API. In the next blog post in this series, I will center the discussion on app authentication and we will take a dive deep into the differences between how app authentication works in the Office 365 environment versus an on-premises farm.
I have complimented this blog post with a few sample projects I have written with the Visual Studio 2012 Release Candidate. The download is named TheCsomRestPartyPack.zip and it can be downloaded from here in the members page of the Critical Path Training website. If you are not already a member, you can sign up by supplying your email address.
Writing Client-side JavaScript using CSOM
It's pretty easy to get started with programming client-side JavaScript using CSOM. That's because all the code you need to get up and running is automatically added by Visual Studio 2012 and the SharePoint Tools when you create a new SharePoint-hosted app. Note that when you create a new SharePoint-hosted app project, Visual Studio also adds the JavaScript source file and required links for the jQuery core library. If you are beginning to develop SharePoint apps and you haven't yet become familiar with jQuery, now is the time to pick up a jQuery book or to work through some of the tutorials you can find at jQuery.com.
Now imagine you have just created your first SharePoint-hosted app project in Visual Studio 2012. Let's start off by examining the small bit of JavaScript code that Visual Studio 2012 adds into the app's start page named default.aspx.
$(document).ready(function () {
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () { sharePointReady(); });
});
This code uses the jQuery document ready event handler and an anonymous function to trigger its execution just after the browser has finished loading the DOM and the elements of the page are ready to access. Inside the anonymous function, there is a single line of code that calls to a JavaScript function supplied by SharePoint Foundation named SP.SOD.executeFunc.
It's important that you understand why the call to SP.SOD.executeFunc is necessary. It has to do with forcing the download of an essential JavaScript source file named sp.js. While the standard SharePoint master pages link to this JavaScript source file and several others, they are not linked in such a way that they are guaranteed to be downloaded and available for use in the browser before the page is displayed to the user. Instead, they are linked using a script-on-demand (SOD) mechanism.
The benefit of SOD to the user is that pages are displayed faster. More specifically, the user isn't required to wait until a bunch of JavaScript code downloads from across the network before seeing a page. The issue caused by SOD for a developer like yourself is that you must supply code to force the download of specific JavaScript source files such as sp.js before you can call the functions they contain. The file named sp.js is particularly important because it contains the core functions of CSOM.
If we examine the parameters passed in the call to SP.SOD.executeFunc, you can see the first two parameters pass the name of the sp.js source file and a JavaScript function inside that source file named SP.ClientContext.
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () { sharePointReady(); });
When you call SP.SOD.executeFunc, the method's implementation downloads sp.js and then executes a function inside it named SP.ClientContext. The execution of this function initializes the client context which represents the heart and soul of the CSOM programming model. After that, the method's implementation executes whatever function that has been passed as the third parameter. The code supplied by Visual Studio provides an anonymous function that executes a function named sharePointReady. You can rewrite this code to simplify it and clean it up a bit to provide the generic starting point for any client-side code that uses CSOM.
$(function () {
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', sharePointReady );
});
function sharePointReady() {
// code added here can begin to use CSOM
}
The important thing to observe here is that there is a pattern where you force the download of sp.js and then call a custom function where it is safe to use CSOM. If you use the code supplied by Visual Studio, the function where you can begin using CSOM is named sharePointReady. Now let's look at a longer code listing where the sharePointReady method is implemented to retrieve the Title property of the app web using CSOM.
$(function () {
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', sharePointReady);
});
// create page-level variables to hold client context and web
var context;
var web;
function sharePointReady() {
// assign values to page-level variables
context = new SP.ClientContext.get_current();
web = context.get_web();
// provide CSOM with instructions to load info about current web
context.load(web);
// issue asynchronous call across network for CSOM to carry out instructions
context.executeQueryAsync(onSuccess, onFail);
}
function onSuccess() {
$("#message").text("Site title: " + web.get_title());
}
function onFail(sender, args) {
$("#message").text("Error: " + args.get_message());
}
The code in this listing creates two page-level variables named context and web to reference two CSOM objects. The first CSOM object is the client context which is referenced using a call to new ClientContext.get_current(). You can think of the client context as your connection back to the site which served up the current page. The second CSOM object referenced by the web variable represents the current SharePoint site (the app web in this example) which is retrieved by calling the get_web method on the client context object.
One of the most important concepts in CSOM programming is that many of its objects have to be initialized by calling across the network before their properties contain meaningful values. For example, the object referenced by the web variable does not have valid property values after the call to get_web. Instead, you must call context.load(web) to provide CSOM with instructions to populate its property values and then you must call context.executeQueryAsync to make an asynchronous call across the network in which CSOM will actually retrieve the property value for the current site and populate the object referenced by the web variable.
It's also important to observe that the call across the network in this example is made asynchronously. If client-side code running in the browser were to make a call across the network in a synchronous fashion, it would produce the undesired effect of freezing the user interface. This would result in an unacceptable user experience so it must be avoided. When writing client-side code which calls from the browser across the network you must ensure you are using asynchronous calls which is accomplished in CSOM by calling the context.executeQueryAsync method.
When you call context.executeQueryAsync you must pass two callback functions which I have named onSuccess and onFail. The first callback function named onSuccess is called by CSOM if the call across the network completes without errors. The second callback function named onFail is what CSOM calls if the call across the network experiences an error. In this simple example the onSuccess function has been written to retrieve the Title property of the app web by calling web.get_title. It also uses the jQuery style of coding to write the Title property value into the div elements with the id of message where it can be seen by the user.
$("#message").text("Site title: " + web.get_title());
In the sample code I have added to TheCsomRestPartyPack.zip, I have included a SharePoint-hosted app project named SharePointAppCSOMDemo. This SharePoint app contains client-side JavaScript code which demonstrates getting more involved with the CSOM. Here is a screenshot of the app's start page which shows its basic functionality.

For example, there is JavaScript code in the SharePointAppCSOMDemo project which demonstrates updating the app web's Title property, adding a new list and switching back and forth between a custom master page and the standard master page for SharePoint-hosted apps named app.master. For example, you can use CSOM to switch the master page for the current site using the following JavaScript code.
function onUseCustomMaster() {
var masterUrl = web.get_serverRelativeUrl() +
"/_catalogs/masterpage/CustomApp.master";
web.set_masterUrl(masterUrl);
web.update();
ctx.executeQueryAsync(refreshPage, onError);
}
I will now conclude this section by summarizing some of the key points of programming client-side JavaScript using CSOM. First, your code must ensure that the file named sp.js has been downloaded before you can use any functions or objects provided by CSOM. Second, you must initialize certain CSOM objects before you use them. Finally, you initialize CSOM objects and perform other actions such as creating new lists by calling across the network in an asynchronous fashion using a call to executeQueryAsync.
Writing Client-side JavaScript using the REST API
As you have probably noticed over the last few years, REST-based Web services have become increasing popular throughout the IT industry and particularly within Microsoft. SharePoint 2013 introduces a new REST API that expose the much of the same functionality that is available through CSOM. This is great news for developers writing client-side JavaScript code because the new REST API often results in code that is easier to write and maintain when compared to programming with CSOM. The new REST API also provides essential entry points for servers-side code which does not run on the.NET Framework which does not have the ability to use CSOM. Because of this, you can say that the new REST API makes SharePoint 2013 a much more "open" platform.
A significant percentage of the new REST API has been created in accordance with a emerging web-based protocol known as Open Data Protocol (OData). The OData protocol has been designed to allow client applications to query and update data using standard HTTP verbs and to send and retrieve data in standardized formats such as Atom, JSON or plain XML. The OData protocol also includes provisions for common data retrieval tasks such as filtering, ordering and pagination. If you are planning to become proficient with the new REST API in SharePoint 2013, you will find that the OData website is a very useful resource.
http://www.odata.org/
Programming against the REST API in SharePoint 2013 is quite different than programming with CSOM. The first thing you will notice is that using the REST API does not require a SharePoint-specific JavaScript class library. Therefore, you do need to supply code to force the download of a JavaScript source file. Instead, the REST API requires you to parse together URLs that represents target objects such as sites, lists and items. Therefore, your first challenge is learning how to parse together these URLS according to the rules outlines by the OData protocol along with additional specifics added by SharePoint 2013. For example, you might be required to parse together an URL whose target object is a SharePoint site. Additionally, you might be required to add a query string parameter to indicate which property or properties you want to retrieve.
As you get started with the REST API, you can begin learning how to create the URLs required for querying data just using a browser. For example, you can type an URL into the address bar of the Internet Explorer and execute the request against a SharePoint site to see the results. For example, imagine there is a SharePoint 2013 site accessible at http://wingtipserver. You can type the following URL into the browser to execute an HTTP GET request to retrieve the Title property of the current site.
http://wingtipserver/_api/web/?$select=Title
The URL is made up of three basic parts. First, there is the base URL of http://wingtipserver/ that points to the site. In OData terminology this is known as the service root. The next part of the URL is the resource path that points to the target site which in this case is _api/web/. Finally, there are the query options which involve a single query string parameter in this case of ?$select=Title which tells the SharePoint host environment to return the site's Title property. When you execute a GET request through the browser using this URL, the SharePoint host environment returns the following XML result.
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" >
<id>http://wingtipserver/_api/Web</id>
<category term="SP.Web" />
<content type="application/xml">
<m:properties>
<d:Title>Wingtip Test Site</d:Title>
</m:properties>
</content>
</entry>
By default, the SharePoint host environment responds to REST calls by returning XML which is structured according to a standard known as Atom Syndication Format. However, when making REST calls with JavaScript code it is often easier to request that results are returned in an easier-to-use format known as JavaScript Object Notation (JSON). This can be accomplished by adding the accept header to the GET request. For example, if you submit a GET request using the exact same URL and you include the accept header with a value of application/JSON, the result that comes back now looks like this.
{
"d": {
"__metadata": {
"id": "http://wingtipserver/_api/Web",
"uri": "http://wingtipserver/_api/Web",
"type": "SP.Web"},
"Title": "Hello REST"
}
}
When the result is returned in JSON format, it can be easily transformed into a JavaScript object. This means you can access the data returned from a REST call without any need to parse through XML. This is a significant productivity win in many scenarios. If you use the getJSON function supplied by jQuery, you don't even have to convert the JSON result from text into a JavaScript object because that is done for you automatically.
Now I have covered enough background information to present the 'hello world' JavaScript code behind the start page of a SharePoint-hosted app which uses the REST API. To be consistent with the earlier example I showed using CSOM, our first REST API example will query the Title property of the app web. Note that the code in the following listing uses a standard JavaScript variable named _spPageContextInfo which the SharePoint host environment adds to every page.
$(function () {
// parse together URL for HTTP GET request
var requestUri = _spPageContextInfo.webAbsoluteUrl + "/_api/Web/?$select=Title";
// transmit GET request to SharePoint host environment
jqhxr = $.getJSON(requestUri, null, onSuccess);
jqhxr.error(onFail);
});
function onSuccess(data) {
var appWebTitle = data.d.Title;
$("#message").text(appWebTitle);
}
function onFail(errorObject, errorMessage) {
$("#message").text("Error: " + errorMessage);
}
As you can see, the _spPageContextInfo variable exposes a property named webAbsoluteUrl which makes it possible to determine the service root of the current site. You parse together the URL required by taking this service root and appending the resource path to specify a target object (e.g. the current site) and a query string to include any query options you need. Once you have parsed together the correct URL, you can then transmit the HTTP GET request to the SharePoint host environment using the jQuery function named getJSON.
Just as in the case of programming against CSOM, you should ensure that calls across the network are made using an asynchronous technique so you do not freeze the user interface of the browser. Fortunately, all the jQuery functions such as getJSON, ajax and load have been implemented with asynchronous behavior. You just need to supply callback methods which are automatically executed when the result is returned from across the network. In this simple example, the callback method named onSuccess executes and passes a parameter named data with represents the JSON result. When using the getJSON method, you will find that the callback method passes a parameter which has already been converted from text into a JavaScript object. You can access the Title property of the SharePoint site by simply accessing the Title property of a JavaScript object.
function onSuccess(data) {
var appWebTitle = data.d.Title;
$("#message").text(appWebTitle);
}
The sample code in TheCsomRestPartyPack.zip contains a SharePoint-hosted app project named SharePointAppRESTDemo. This sample SharePoint app creates a Customers list in the app web at installation time and populates this list with a handful of sample customer items. I created the Customers list in this SharePoint app mainly so the app can demonstrate how to program against list items using the REST API. I also wrote all the JavaScript code in this app that is needed to demonstrate the full set of CRUD (create, read, update and delete) functionality that the REST API makes possible. Here's a screenshot of the start page and the Add New Customer dialog which will give you an idea of what this app can do.

I will leave it to you to explore all the code in this sample app. There is far too much JavaScript code to walk through it all in this post. However, I'd like to present a few chosen listings of the JavaScript code from this app to make a few more points for those getting started.
First, I would like to discuss returning a set of data in JSON format and rendering it as HTML. This is often accomplished using a separate JavaScript library. In this sample app I am using one of my favorites which is jsrender. This JavaScript library is based on its own unique template syntax which makes it fairly easy to convert a JSON result into an HTML element such as a list or a table. Here is a slightly watered-down version of the code in the SharePointAppRESTDemo app that returns the Customers list as a JSON result and then uses the jsrender library and its powerful template syntax to convert the list items into an HTML table for display on the app's start page.
function onDataReturnedListing(data) {
// clear out the target element on the start page
$("#results").empty();
// obtain the JavaScript object array from the JSON result
var odataResults = data.d.results;
// create the header row for the HTML table
var tableHeader = "<thead>" +
"<td>Last Name</td>" +
"<td>First Name</td>" +
"<td>Work Phone</td>" +
"</thead>";
// create a new table using jQuery syntax
var table = $("<table>", { id: "customersTable" }).append($(tableHeader));
// create a rendering template using jsrender syntax
var renderingTemplate = "<tr>" +
"<td>{{>Title}}</td>" +
"<td>{{>FirstName}}</td>" +
"<td>{{>WorkPhone}}</td>" +
"</tr>";
// use the rendering template to convert JSON result to an HTML table
$.templates({ "tmplTable": renderingTemplate });
table.append($.render.tmplTable(odataResults));
// write the table into a target element on the start page
$("#results").append(table);
}
From this code you should be able to see the value of using the jsrender library. It makes it so much easier to write and maintain JavaScript code that converts data from the JSON format into HTML elements. I find that I am more impressed with the jsrender library and what it can do each time I use it. To be fair and impartial I must admit that my friends, AC and Scot, both tell me they prefer the knockout library hands down over jsrender. But then again, they are both Republican golfers and so I have to take what they say with a grain of salt. They probably just prefer knockout because they are accustom to having someone else do all the hard work for them and to have this work done out of sight where they don't have to watch. Oh, but I digress.
I'd like to show one final code snippet from the SharePointAppRESTDemo app to give you an idea of how to write code that actually updates list data within a SharePoint site. Here is the JavaScript code that is used to add new items to the Customers list.
// get new Customer data from new customer dialog
var LastName = returnValue.LastName;
var FirstName = returnValue.FirstName;
var WorkPhone = returnValue.WorkPhone;
// parse together URL with resource path for target list
var requestUri = _spPageContextInfo.webAbsoluteUrl +
"/_api/Web/Lists/getByTitle('Customers')/items/";
// create JavaScript object to create headers for request
var requestHeaders = {
"accept": "application/json",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
}
// create JavaScript object with new customer data
var customerData = {
__metadata: { "type": "SP.Data.CustomersListItem" },
Title: LastName,
FirstName: FirstName,
WorkPhone: WorkPhone
};
// convert customer data from JavaScript object to string-based JSON format
requestBody = JSON.stringify(customerData);
// transmit HTTP POST operation to SharePoint host environment to add new list item
$.ajax({
url: requestUri,
type: "Post",
contentType: "application/json",
headers: requestHeaders,
data: requestBody,
success: onSuccess,
error: onError
});
I'd like to point out that the call to the ajax function includes a header named X-RequestDigest. This header is important because it contains an essential piece of information known as the form digest value. The SharePoint host environment relies on the form digest value to protect against replay attacks. The important thing to understand is that the SharePoint host environment will reject any REST call that attempts to modify content which does not contain the X-RequestDigest header with a valid form digest value.
Fortunately, it is pretty easy to obtain the form digest value because it gets added to all pages by the standard SharePoint master pages in a div element with an id of __REQUESTDIGEST. Therefore, you can read the form digest value on any standard page served up by the SharePoint host environment using this jQuery syntax.
var formDigestValue = $("#__REQUESTDIGEST").val()
You should also observe how data for the new list item is passed from this JavaScript code to the SharePoint host environment. It is done by creating a JavaScript object that is converted into a text-based JSON format using a call to the JSON.stringify function. The JavaScript object is initialized with properties named to match the site columns in the target list along with a property named __metadata. The __metadata property must be initialized with an inner JavaScript object that contains a property named type. The type property in this example is given a value of SP.Data.CustomersListItem which is a predictable type name given by the SharePoint host environment when you create a list with a title of "Customers". In other scenarios you might have to query a SharePoint list using the REST API in order to determine what value should be assigned to the type property when adding new items to a list.
Before moving on to server-side programming, let's summarize some of the key points of programming client-side JavaScript using the REST API. First, you must learn how to parse together the URLs required for making REST API calls according to the OData protocol and the specifics used by SharePoint 2013 to create resource paths which can be used to reference target objects such as sites, lists and list items. Second, passing input data and returning results in JSON format usually provides the easiest way to program in JavaScript. Third, the jQuery library is your friend because it provides convenient functions to transmit HTTP requests to the SharePoint host environment using whatever HTTP verb is required for the current request at hand. Last of all, you should get to know some of the great JavaScript libraries that are available for free. I demonstrated using jsrender in this post but there is also a great deal of excitement around other libraries such as knockout and SignalR.
Writing Server-side Code in Cloud-hosted SharePoint Apps
Now we will turn our attention from client-side programming to server-side programming. One favorable aspect of server-side programming for many experienced .NET developers is that you can leave behind the loosely-typed nature of JavaScript and begin coding in C# or VB which provides the benefits of compile-time type checking, better IntelliSense and full access to the libraries of the .NET Framework.
Also keep in mind that your server-side code runs in a standard ASP.NET application and not inside the SharePoint environment. Therefore, you don't have to worry about many of the strange constraints and SharePoint-isms that require your attention when writing server-side code in a farm solution such as crippling the local SharePoint farm's performance by forgetting to properly dispose of SPSite objects in memory.
For the sample code I will use to demonstrate server-side programming in this post, I will use two SharePoint app projects that have been designed to use internal authentication and to programming exclusively against the app web. I am using this scenario to simplify things because a cloud-hosted SharePoint app that uses internal authentication does not require explicit programming to manage app authentication. By eliminating any code to deal with app authentication, I can focus on the core fundamentals of CSOM and REST API programming.
The other nice thing about cloud-hosted SharePoint app projects that use internal authentication is that you can just open them in Visual Studio and test them out by pressing the {F5} key. However, you should take note that you must have your development environment configured with a local SharePoint 2013 farm to run the cloud-hosted app projects I will be discussing over the next two sections. If you want to learn about how I configured these sample apps to use internal authentication, you can read my post titled Configuring a Cloud-hosted SharePoint App to Use Internal Authentication.
Writing Server-side C# code that uses CSOM
Getting started with with server-side CSOM code in a cloud-hosted app is easier than it is with client-side JavaScript code. The first reason is that you have the benefit of compile-time type checking. The second reason is that you are able to use synchronous execution instead of asynchronous execution so your server-side code doesn't require callback methods like the JavaScript code I showed earlier.
The C# code I will show in this section is available in TheCsomRestPartyPack.zip download in a sample SharePoint app project named CloudAppCsomDemo. While this sample app will not win any awards for user interface design, it provides some simple examples of server-side C# code and a few ideas for cloud-hosted app designs. Here is a screenshot of the app's start page.

Let's see how easy it is to get started with programming CSOM on the server. The CloudAppCsomDemo app contains the following server-side C# code in the Page_Load method of the app's start page which retrieves the incoming SPAppWebUrl query string parameter with the app web URL and then uses CSOM to synchronously retrieve the app web's Title property and display it on a ASP.NET label control named lblAppWebTitle.
protected void Page_Load(object sender, EventArgs e) {
// retrieve app web URL from incoming query string parameter
string appWebUrl = Page.Request["SPAppWebUrl"];
using (ClientContext clientContext = new ClientContext(appWebUrl)) {
Web appWeb = clientContext.Web;
clientContext.Load(appWeb);
clientContext.ExecuteQuery();
lblAppWebTitle.Text = appWeb.Title;
}
}
At this point you're probably thinking that writing server-side code using CSOM looks pretty easy compared to writing it with client-side JavaScript. Well, in many scenarios that is indeed the case. However, there is a catch. If you add server-side CSOM code like this behind the start page of a cloud-hosted app, the user will be sitting around and waiting for the app's start page to load while your code is making round trips between the remote web and the SharePoint host environment. If your code is doing a significant amount of initialization work with the CSOM, the wait time to load and display the start page might approach an unacceptable amount of time.
A better design can often result from avoiding server-side CSOM code behind the app's start page because it results in a start page which loads faster without unnecessary delay. While many cloud-hosted apps will require CSOM code at start-up, this code can be moved into secondary pages and handlers which can be called from the start page asynchronously using client-side JavaScript. Let's walk through an example of how to create such a design.
We will begin be adding code to the app's start page Default.aspx to take the incoming SPAppWebUrl query string parameter which points to the app web URL and to cache it for other pages and handlers to use.
// code added to start page
protected void Page_Load(object sender, EventArgs e) {
// cache url to web app for other pages
Cache["SPAppWebUrl"] = Page.Request["SPAppWebUrl"];
}
The next step is to create a secondary page or handler which does the actual work against the CSOM. I have found that adding a Generic Handler project item (i.e. a handler with an .ashx extension) into the ASP.NET project for the remote web provides an easy and effective way to create a server-side entry point which can be called from client-side JavaScript on the start page. For example, you can create a generic handler named appWebTitle.ashx and implement it with the following code to return the app web Title property as simple text.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.SharePoint.Client;
namespace CloudAppCsomDemoWeb.Pages {
public class appWebTitle : IHttpHandler {
public void ProcessRequest(HttpContext httpContext) {
// retrieve app web URL from cache
string appWebUrl = httpContext.Cache["SPAppWebUrl"].ToString();
string appWebTitle = string.Empty;
using (ClientContext clientContext = new ClientContext(appWebUrl)) {
Web appWeb = clientContext.Web;
clientContext.Load(appWeb);
clientContext.ExecuteQuery();
appWebTitle = appWeb.Title;
}
// return response as simple text
httpContext.Response.ContentType = "text/plain";
httpContext.Response.Write(appWebTitle);
}
public bool IsReusable { get {return false;} }
}
}
Once you have created a generic handler like this, you can call it and load its contents into a div element using JavaScript behind that start page which calls the jQuery load function.
$("#appwebtitle").load("/Pages/appWebTitle.ashx");
You can take this type of design one step further by implementing a generic handler to return its results in other formats such as HTML, XML or JSON. Here's an example of a generic handler that uses CSOM to discover the lists that exist within the app web and to return the title of each of these lists using an HTML <ol> element.
public void ProcessRequest(HttpContext httpContext) {
string appWebUrl = HttpContext.Current.Cache["SPAppWebUrl"].ToString();
using (ClientContext clientContext = new ClientContext(appWebUrl)) {
// use CSOM to retrieve collection of lists
Web appWeb = clientContext.Web;
ListCollection appWebLists = appWeb.Lists;
clientContext.Load(clientContext.Web);
clientContext.Load(clientContext.Web.Lists);
clientContext.ExecuteQuery();
// set up HtmlTextWriter to write to response output stream
httpContext.Response.ContentType = "text/html";
StreamWriter innerWriter = new StreamWriter(httpContext.Response.OutputStream);
HtmlTextWriter writer = new HtmlTextWriter(innerWriter);
// create an HTML ol element with list of lists in app web
writer.RenderBeginTag(HtmlTextWriterTag.Ol);
foreach (var list in appWebLists) {
writer.RenderBeginTag(HtmlTextWriterTag.Li);
writer.Write(list.Title);
writer.RenderEndTag(); // </li>
}
writer.RenderEndTag(); // <ol>
// flush results to output stream and clean up
writer.Flush();
writer.Dispose();
}
}
Let's look at one final example of server-side C# code which uses the CSOM to create a new list in the app web. The start page contains an ASP.NET UpdatePanel control which provides the user with the ability to add new lists to the app web. The UpdatePanel allows for a simple design where you can add server-side code behind a command button without forcing page postbacks. The code behind the Create New List command button looks like this.
// retrieve title and type for new list from server-side controls
string ListTitle = txtNewListTitle.Text;
int ListType = Convert.ToInt32(lstListType.SelectedValue);
// retrieve URL to app web
string appWebUrl = Page.Request["SPAppWebUrl"];
// use CSOM to create new list
using (ClientContext clientContext = new ClientContext(appWebUrl)) {
ListCreationInformation newList = new ListCreationInformation();
newList.Title = ListTitle;
newList.Url = "Lists/" + ListTitle;
newList.QuickLaunchOption = QuickLaunchOptions.On;
newList.TemplateType = ListType;
clientContext.Web.Lists.Add(newList);
try {
clientContext.ExecuteQuery();
lblStatus.Text = "New " + lstListType.SelectedItem.Text +
" created with title of " + ListTitle;
}
catch (Exception ex) {
lblStatus.Text = "ERROR: " + ex.Message;
}
}
// add client-side script to asynchronously reload lists
string updateScript = "$('#appweblists').load('/Pages/appWebLists.ashx');";
ScriptManager.RegisterClientScriptBlock(upNewList,
upNewList.GetType(),
upNewList.ClientID,
updateScript, true);
As you can see, it is relatively straight forward to create lists and other types of SharePoint site elements using server-side C# code which programs against the CSOM. At the end of this listing I have added a call to ScriptManager.RegisterClientScriptBlock in order to execute the client-side jQuery code required to retrieve the set of lists from the app web which includes the list that has just been created.
I will now conclude this section by summarizing some of the key points of programming server-side C# code using the CSOM. First, many programmers find this type of programming easier than using JavaScript because there is compile-time type checking and full access to the libraries of the .NET Framework. Second, the CSOM programming is a bit easier on the server because you call across the network synchronously using ExecuteQuery without having to worry about freezing the user interface as you do with client-side code. Third, there is often a need for loading content asynchronously, but this often means exposing additional entry points in the remote web project such as generic handler and web service methods and calling them from client-side JavaScript code. Finally, and best of all, you can use all the little tricks and techniques that the ASP.NET Framework has to offer without the frustrating limitations and constraints imposed on server-side code in farm solutions which run inside the SharePoint environment.
Writing Server-side C# code that uses the REST API
To say that writing server-side C# against the new REST API is more tricky than the CSOM is a bit of an understatement. Writing server-side C# code using the REST API can be a downright pain in your ASP. I think you will agree after seeing the code listings in this section.
The download named TheCsomRestPartyPack.zip contains a sample SharePoint app project named CloudAppRestDemo. This sample app provides the exact same functionality and user interface as the CloudAppCsomDemo app. The only difference is that one uses CSOM to talk to the SharePoint host environment where the other uses the REST API. The app which uses the REST API requires more C# code than the CSOM-based app to accomplish the same tasks. After seeing the comparison you will likely agree that C# code using the REST API is harder to write and maintain.
Let's start by examining the code in the Page_Load method of the app's start page which uses the REST API to retrieve the app web Title property and display it on a ASP.NET label control named lblAppWebTitle.
// retrieve URL to app web
string appWebUrl = Page.Request["SPAppWebUrl"];
// create URL for REST call to query for app web Title property
Uri uri = new Uri(appWebUrl + "/_api/web/?$select=Title");
// transmit HTTP GET request to SharePoint host environment
HttpWebRequest requestGet = (HttpWebRequest)WebRequest.Create(uri);
requestGet.Credentials = CredentialCache.DefaultCredentials;
requestGet.Method = "GET";
HttpWebResponse responseGet = (HttpWebResponse)requestGet.GetResponse();
// retrieve Title property from XML returned by SharePoint host environment
XDocument doc = XDocument.Load(responseGet.GetResponseStream());
XNamespace ns_dataservices = "http://schemas.microsoft.com/ado/2007/08/dataservices";
lblAppWebTitle.Text = doc.Descendants(ns_dataservices + "Title").First().Value;
The code in this listing begins by parsing together the proper URL to make the REST call which returns the app web's Title property in an ATOM-based XML result. Next, the code prepares and transmits an HTTP GET request to the SharePoint host environment using the new HttpWebRequest class that was introduced in .NET 4.0. When the call to the GetResponse method returns, you have to extract the Title property value from the returned XML document. If you are not familiar with LINQ to XML and the XDocument class, you should get up to speed on them because they make this type of programming much easier than using the older XML-based APIs of the .NET Framework.
As you can see in the listing above, the Descendants method of the XDocument class makes it much easier to extract the namespace-qualified Title property out of the following XML result.
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" >
<id>http://big-long-url-to-app-web/_api/Web</id>
<category term="SP.Web" />
<content type="application/xml">
<m:properties>
<d:Title>Wingtip Test Site</d:Title>
</m:properties>
</content>
</entry>
Now let's look at the generic handler which has been written to use the REST API discover the set of lists in the app web and to generate an HTML list element which can be used for display on the start page. Here is the code inside the ProcessRequest method of the generic handler that accomplishes this work.
public void ProcessRequest(HttpContext context) {
// prepare response as HTML and set up HtmlTextWriter
context.Response.ContentType = "text/html";
StreamWriter innerWriter = new StreamWriter(context.Response.OutputStream);
HtmlTextWriter writer = new HtmlTextWriter(innerWriter);
// get URL for app web
string appWebUrl = context.Cache["SPAppWebUrl"].ToString();
// create URL for REST API to retrieve lists from app web
Uri uri = new Uri(appWebUrl + "/_api/web/lists/?$select=Title");
// transmit HTTP GET request to SharePoint host environment
HttpWebRequest requestGet = (HttpWebRequest)WebRequest.Create(uri);
requestGet.Credentials = CredentialCache.DefaultCredentials;
requestGet.Method = "GET";
HttpWebResponse responseGet = (HttpWebResponse)requestGet.GetResponse();
// load XML result in XDocument object
XDocument doc = XDocument.Load(responseGet.GetResponseStream());
XNamespace ns_dataservices =
"http://schemas.microsoft.com/ado/2007/08/dataservices";
// create an HTML ol element with list of lists in app web
writer.RenderBeginTag(HtmlTextWriterTag.Ol);
foreach (var list in doc.Descendants(ns_dataservices + "Title")) {
writer.RenderBeginTag(HtmlTextWriterTag.Li);
writer.Write(list.Value);
writer.RenderEndTag(); // </li>
}
writer.RenderEndTag(); // </ol>
// flush generated HTML to response stream and clean up
writer.Flush();
writer.Dispose();
}
Once again, the REST API requires that you parse together the URL for a GET request that queries the app web for the current set of lists. The code in this listing prepares an HTTP GET request that is sent and received using HttpWebRequest and HttpWebResponse objects. At the end there is code written using the XDocument class which enumerates through the returned XML document to create an HTML list element which contains a list item with the Title property of each list which is written into the generic handler's output stream.
When it comes time to modify content in a SharePoint site such as creating a list is when programming C# against the REST API gets pretty grungy. For example, you need to acquire the form digest value that was discussed earlier this post. However, the form digest value is not readily available as it was in the previous example which involved writing JavaScript behind a page served up from a SharePoint site. Instead, you must make an HTTP POST request with an URL that queries the REST API for context information using a URL that ends with _api/contextinfo. Here is an example of a utility function I wrote named GetFormDigest which calls to the SharePoint host environment to acquire a Form Digest value that can then be used in subsequent requests that modify content.
private string GetFormDigest(){
string appWebUrl = Cache["SPAppWebUrl"].ToString();
Uri uri = new Uri(appWebUrl + "/_api/contextinfo");
HttpWebRequest requestPost = (HttpWebRequest)WebRequest.Create(uri);
requestPost.Credentials = CredentialCache.DefaultCredentials;
requestPost.Method = "POST";
requestPost.ContentLength = 0;
HttpWebResponse responsePost = (HttpWebResponse)requestPost.GetResponse();
XDocument doc = XDocument.Load(responsePost.GetResponseStream());
XNamespace ns_dataservices =
"http://schemas.microsoft.com/ado/2007/08/dataservices";
return doc.Descendants(ns_dataservices + "FormDigestValue").First().Value;
}
In addition to acquiring a form digest value, creating a new list with the REST API requires you to parse together the payload for the request body using either an ATOM-based XML format or JSON. In our scenario the XML payload must contain information about the new list that is being created. Since we are working with C# instead of JavaScript, it is easier to use the ATOM-based XML format instead of JSON. The code behind Default.aspx contains a protected string constant named AtomXmlForNewList which provide a template for creating the XML required to create a new list.
protected string AtomXmlForNewList = @"
<entry xmlns='http://www.w3.org/2005/Atom'
xmlns:d='http://schemas.microsoft.com/ado/2007/08/dataservices'
xmlns:m='http://schemas.microsoft.com/ado/2007/08/dataservices/metadata' >
<category term='SP.List'
scheme='http://schemas.microsoft.com/ado/2007/08/dataservices/scheme' />
<content type='application/xml'>
<m:properties>
<d:Title>@Title</d:Title>
<d:BaseTemplate m:type='Edm.Int32'>@ListTypeId</d:BaseTemplate>
</m:properties>
</content>
</entry>";
Using a string-based template like this, your code just needs to do a search-and-replace operation on the two placeholders named @Title and @ListTypeId. Then you write the resulting XML document into the body of a POST request that you transmit to the SharePoint host environment. Here's the code in the CloudAppRestDemo app that pulls everything together to create new list in the app web using the REST API.
// create URL with resource path referencing app web's list collection
string appWebUrl = Cache["SPAppWebUrl"].ToString();
Uri uri = new Uri(appWebUrl + "/_api/web/lists/");
// create HttpWebRequest for POST operation with Windows authentication credentials
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.Credentials = CredentialCache.DefaultCredentials;
// add header with form digest value
request.Headers["X-RequestDigest"] = GetFormDigest();
// set format of response body
request.Accept = "application/atom+xml";
// create ATOM-based XML document for creating new list
request.ContentType = "application/atom+xml";
string body = AtomXmlForNewList;
body = body.Replace("@Title", txtNewListTitle.Text);
body = body.Replace("@ListTypeId", lstListType.SelectedValue);
// write create ATOM-based XML document to request body
request.ContentLength = body.Length;
StreamWriter writer = new StreamWriter(request.GetRequestStream());
writer.Write(body);
writer.Flush();
try {
// send synchronous HTTP POST request to SharePoint host environment
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
lblStatus.Text = "New " + lstListType.SelectedItem.Text +
" created with title of " + ListTitle;
}
catch (Exception ex) {
lblStatus.Text = "ERROR: " + ex.Message;
}
So now you have seen a direct comparison between server-side C# code using both CSOM and the REST API. Most developers will agree that using the CSOM is significantly easier. That's because CSOM manages the form digest for you behind the scenes and it doesn't require you to parse together URLs and XML documents. I will prefer using CSOM over the REST API for server-side C# code until someone is able to show me that the REST API has performance advantages or offers functionality not available through the CSOM. But then again, Microsoft's big investment in the REST API was not made for this scenario. Microsoft was incented to create the new REST API for the benefit of client-side JavaScript code and for server-side code not running on the .NET Framework which has no access to CSOM.
Summary
You have just read through a long post which I wrote to get you started with developing SharePoint apps which communicate with the SharePoint host environment using CSOM and the new REST API. As you have seen, there are four basic styles. I typically prefer using the REST API over CSOM when writing client-side JavaScript code because it allows me to work with JSON which integrates well with other JavaScript libraries such as jQuery, jsrender and knockout. However, there are some scenarios where you will find that using CSOM is just as easy or easier. I find it's when I am writing server-side code with C# that there is such a drastic difference in productivity. I will always prefer the CSOM over the REST API in this scenario.
For the purposes of creating a smoother learning path, I avoided any discussion of app authentication and app identity in this post. However, these are essential topics that must be understood by anyone developing cloud-hosted SharePoint apps. Therefore, they will be the focus of the next post in this series that will pick up where this post leaves off.