Getting ClientContext in worker Apps for SharePoint
Communicating with SharePoint in Apps for SharePoint
SharePoint 2013 introduces the new App Model for building customizations and extending the functionality of the SharePoint platform. One of the biggest differences between the new App Model and Full Trust Code we used to work with in the previous versions of SharePoint is the fact that apps’ code executes off the SharePoint servers and Client-Side Object Model (CSOM) is used to communicate with SharePoint.
When working with CSOM, communication with SharePoint is facilitated by the ClientContext. Using CSOM you construct queries for objects and operations which are then sent to SharePoint using the ClientContext. So to put it in other words: you need to instantiate ClientContext before you are able to communicate with SharePoint.
There are a number of ways in which you can create a ClientContext object in your solution. Depending on what kind of solution you are building, you can prompt user for credentials, you can use OAuth or S2S trust between your app-server and SharePoint to get access to data in SharePoint. When building Apps for SharePoint the latest two approaches apply.
In both scenarios the communication process begins with a user starting the app. All the necessary information required to construct the ClientContext is passed automatically and so the app can access data in SharePoint.
When building Apps for SharePoint there are scenarios where the app might need a longer time to process the data. For scalability and stability purposes in such scenarios you would separate the processing part from the app’s interface and would implement it in a separate worker process. Using the app UI the user would request the app to do something. That request would be added to a queue from where it would be picked up and handled by the worker process. Because the worker process is a separate process than the UI, and ideally you wouldn’t want to pass the authentication information along with the data processing request in the queue, the worker process needs to construct its own ClientContext to get access to SharePoint and handle the request.
Because the worker process is a part of the app it can perfectly share app’s ClientID and ClientSecret. Additionally, the worker will know which SharePoint site it needs to access to handle the request. This information can be either tied to the particular worker instance (if the app is built for a specific tenant) or can be passed with the data processing request. The only piece of information that is missing, is the request which is typically used to instantiate ClientContext. Luckily a worker process can instantiate its own ClientContext assuming it has the access to ClientID, ClientContext and the URL of the SharePoint site, using the following code snippet:
Uri targetWeb = new Uri("https://contoso.sharepoint.com"); string targetRealm = TokenHelper.GetRealmFromTargetUrl(targetWeb); var responseToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, targetWeb.Authority, targetRealm); ClientContext clientContext = TokenHelper.GetClientContextWithAccessToken(targetWeb.ToString(), responseToken.AccessToken);
First we need to get the realm information for the connection to the particular SharePoint Site (line 2). With it, we can get the access token (line 3). Note, that because the worker is an automated process and no user information is available, the app must be granted app-only calls permission for this code to work. Finally, with all information in place, using the TokenHelper the worker process can get a hold of a ClientContext to communicate with SharePoint (line 4).
When building Apps for SharePoint, ClientContext is the entry point for interacting with SharePoint. While most samples illustrate how to build it in the app, things look a little different for apps’ worker processes. By using the app identification information and just a few lines of code the app worker process is able to construct its own ClientContext to communicate with SharePoint.