Over the last couple months, I’ve been working on a SharePoint app in my spare time. The app, which is SharePoint hosted, requires site collection permissions and reaches back to the Host App to inspect lists and other objects to identify common issues that impact the performance of SharePoint.

One of the first things I struggled with, though, was how to access the data through the SharePoint Client Object Model in the Host Web. Every code sample out there just works with data within the app, and doesn’t try to go back to the Host Web to get the data. Since there is a security barrier between the app and the Host Web, you can’t access data in the Host Web through the client context of the app. You must retrieve the site through a special method in the SharePoint API called AppContextSite.

If you’re familiar with the SharePoint Client Object Model, then you’ve probably seen samples like this before:

var context;
var web;
var user;

function sharePointReady() {
context = new SP.ClientContext.get_current();
web = context.get_web();
context.load(web,"Title");
context.executeQueryAsync(onGetWebSuccess, onGetWebFail)
}

function onGetWebSuccess() {
$('#message').text('The title of this App is ' + web.get_title());
}

function onGetWebFail(sender, args) {
alert('Failed to get user name. Error:' + args.get_message());
}

This code results in the following output:

This is the easy scenario. If I’m developing a SharePoint-hosted app, then I can easily get to the App Web through the clientcontext.get_current( ) method which returns the current context that the user is running in.

However, if you want to access information in the Host Web, a different approach is required. You might think that you can just load the context of the app using SP.ClientContext and passing the string of the Host Web like so…

var web;
var hostcontext;

function sharePointReady() {
var hostUrl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
hostcontext = new SP.ClientContext(hostUrl);
web = hostcontext.get_web();
hostcontext.load(web, "Title");
hostcontext.executeQueryAsync(onGetWebSuccess, onGetWebFail);
}

function onGetWebSuccess() {
$('#message').text("The title of the host web of this app is " + web.get_title());
}

function onGetWebFail(sender, args) {
alert('Failed to get lists. Error:' + args.get_message());
}

//this is just the sample function that's in all the MS samples

function getQueryStringParameter(paramToRetrieve) {
var params =
document.URL.split("?")[1].split("&");
var strParams = "";
for (var i = 0; i < params.length; i = i + 1) {
var singleParam = params[i].split("=");
if (singleParam[0] == paramToRetrieve)
return singleParam[1];
}
}

 …But nope. As soon as you try to execute a query against anything in that context, this is what you get:

So what is the right way? You need to use an object called the AppSiteContext. If you swap out the sharePointReady function from the previous example with this…

function sharePointReady() {
var hostUrl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
currentcontext = new SP.ClientContext.get_current();
hostcontext = new SP.AppContextSite(currentcontext, hostUrl);
web = hostcontext.get_web();

currentcontext.load(web, "Title");
currentcontext.executeQueryAsync(onGetWebSuccess, onGetWebFail);
}

Additionally, you must give the app read access to the Host Site Collection through the App Manifest.

Once you configure this, then you get the output we’re expecting:

The AppContextSite uses the current context to load the Host Web Context. In the background, the SharePoint client object model is brokering all the tokens and fun Oauth security for you so that the App can act on your behalf when it accesses the Host Web.

For those of you who are REST purists, an example of doing the same thing is on the this Technet article [http://msdn.microsoft.com/en-us/library/fp179927.aspx]. But in my app, I’m using the Client Object Model and there really weren’t any examples out there that showed how to do this using CSOM.