SharePoint Context problem in Provider Hosted App with MVC application

This is very common and frustrating problem being found when user create a new provider hosted app using the template provided by Visual Studio.

User create a provider hosted app with option Asp.Net MVC. Two project in the same solution got created:

  • App project (which will be deployed on the SharePoint App Catalog)
  • Web Project (which will be deployed on Azure)

User deploy these projects as it is on Azure and SharePoint successfully. But when try to start the app, received the below error:

“Please try again by launching the app installed on your site.”

This is frustrating because developer thinks this is something related to the configuration but the root cause of this error is unavailability of context.

To resolve this issue, you need to do the following changes:

 

  • Open SharePointContext.cs file and replace the GetSharePointContext(HttpContextBase httpContext) definition with the below code:

 

   public SharePointContext GetSharePointContext(HttpContextBase httpContext)    {

       if (httpContext == null) {

           throw new ArgumentNullException(“httpContext”);

       }

       // Commented out to allow it to work without the SPHostUrl being passed around

       //Uri spHostUrl = SharePointContext.GetSPHostUrl(httpContext.Request);

       //if (spHostUrl == null)

       //{

       // return null;

       //}

       SharePointContext spContext = LoadSharePointContext(httpContext);

       if (spContext == null || !ValidateSharePointContext(spContext, httpContext))

       { spContext = CreateSharePointContext(httpContext.Request);

           if (spContext != null)

           {

               SaveSharePointContext(spContext, httpContext);

           }

       }

       return spContext;

   }

 

  • Replace the definition of the method ValidateSharePointContext(SharePointContext spContext, HttpContextBase httpContext): with the below code:

 

protected override bool ValidateSharePointContext(SharePointContext spContext, HttpContextBase httpContext)

{

SharePointAcsContext spAcsContext = spContext as SharePointAcsContext;

if (spAcsContext != null)

{

// Commented out to allow it to work without the SPHostUrl being passed around

//Uri spHostUrl = SharePointContext.GetSPHostUrl(httpContext.Request);

string contextToken = TokenHelper.GetContextTokenFromRequest(httpContext.Request);

HttpCookie spCacheKeyCookie = httpContext.Request.Cookies[SPCacheKeyKey];

string spCacheKey = spCacheKeyCookie != null ? spCacheKeyCookie.Value : null;

// Commented out to allow it to work without the SPHostUrl being passed around

//return spHostUrl == spAcsContext.SPHostUrl &&

return !string.IsNullOrEmpty(spAcsContext.CacheKey) &&

  spCacheKey == spAcsContext.CacheKey &&

  !string.IsNullOrEmpty(spAcsContext.ContextToken) &&

  (string.IsNullOrEmpty(contextToken) || contextToken == spAcsContext.ContextToken);

}

 

return false;

}

  • Make sure the landing page of your App which will receive the initial request with the SPAppToken variable in HTTP Post calls SharePointContext so the session variable will be created. This can be done by adding the [SharePointContextFilter] attribute either on your MVC controller or above your action method.
  • Now context can be accessed in the application using

SharePointContextProvider.Current.GetSharePointContext(HttpContext);

This is the small solution to resolve your problem. Happy SharePointing !!!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s