Using SharePoint REST API in provider-hosted apps


Although the Client-Side Object Model offers you rich capabilities, there are scenarios when you might need to leverage the SharePoint REST API instead. Find out how to leverage SharePoint REST API in provider-hosted apps.

Building Apps for SharePoint

Using the App Model is the new recommended way for building solutions for SharePoint. To support the different requirements it offers different types of apps and APIs for you to use.

One of those types are provider-hosted apps, where the app is hosted externally to SharePoint. A common way to communicate with SharePoint from provider-hosted apps is to leverage the Client-Side Object Model (CSOM). When building provider-hosted apps Visual Studio already provides you with all the necessary plumbing allowing you to focus on the interaction with SharePoint and its services.

REST vs. CSOM

Microsoft has done some great work extending the capabilities of CSOM in SharePoint 2013. There are however still situations when you might need, or prefer to, use SharePoint REST API instead. This might be either due to a personal preference, portability of the code or, on a rare occasion, simply because what you want to do cannot be easily done with CSOM.

Imagine the following scenario: you have a provider-hosted App for SharePoint that reads the Managed Navigation from a SharePoint site, filters out some nodes and presents it to the user. You would need quite some CSOM code only to retrieve all of the Managed Navigation nodes. In comparison, all it’s needed is a single call to the Navigation REST endpoint which will get you all navigation nodes that you can then process. For this to work however you need to make a REST call to SharePoint from your provider-hosted app.

Using SharePoint REST API in provider-hosted apps

Usually, in order to consume a REST endpoint, all you need to do is to execute a web request to the endpoint’s URL. If you would do just that from a provider-hosted app, SharePoint would return the The remote server returned an error: (403) Forbidden error. This is because only authenticated calls are allowed to the REST API by default. And while Visual Studio takes care of all the plumbing when using CSOM for you, you have to do it yourself if you want to use SharePoint REST API in your provider-hosted app.

In order to authenticate your call to the SharePoint REST API all you need to do is to add the Authorization header to the request. This header should contain the access token for your app.

Getting the access token #1

One way to get a hold of the access token is to execute a CSOM request and intercept its request headers:

string accessToken;

private void CallRest() {
    RetrieveAccessToken();

    HttpWebRequest request = HttpWebRequest.CreateHttp(String.Format("{0}/_api/navigation/menustate?mapprovidername='GlobalNavigationSwitchableProvider'", HttpContext.Request.QueryString["SPHostUrl"]));
    request.Accept = "application/json;odata=verbose";
    request.Headers.Add("Authorization", accessToken));
    Stream s = request.GetResponse().GetResponseStream();
}

private void RetrieveAccessToken() {
    ClientContext ctx = spContext.CreateUserClientContextForSPHost();
    ctx.ExecutingWebRequest += ctx_ExecutingWebRequest;
    ctx.ExecuteQuery();
}

private void ctx_ExecutingWebRequest(object sender, WebRequestEventArgs e) {
    accessToken = e.WebRequestExecutor.RequestHeaders.Get("Authorization");
}

The Authorization request header contains the access token that you need to include in your REST web request.

Getting the access token #2

If your provider-hosted app uses AppOnly calls it might be more elegant to construct the access token yourself:

private void CallRest() {
    Uri targetWeb = new Uri(HttpContext.Request.QueryString["SPHostUrl"]);
    string targetRealm = TokenHelper.GetRealmFromTargetUrl(targetWeb);
    var responseToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, targetWeb.Authority, targetRealm);
    
    HttpWebRequest request = HttpWebRequest.CreateHttp(String.Format("{0}/_api/navigation/menustate?mapprovidername='GlobalNavigationSwitchableProvider'", HttpContext.Request.QueryString["SPHostUrl"]));
    request.Accept = "application/json;odata=verbose";
    request.Headers.Add("Authorization", String.Format("{0} {1}", responseToken.TokenType, responseToken.AccessToken));
    Stream s = request.GetResponse().GetResponseStream();
}

With the Authorization request header set, you will be able to call the SharePoint REST API.

Summary

Although the Client-Side Object Model offers you rich capabilities, there are scenarios when you might need to leverage the SharePoint REST API instead. If you want to use the SharePoint REST API in your provider-hosted app you have to add the Authorization request header that you can either retrieve from a CSOM call or construct yourself.

Others found also helpful: