/// <summary>
 /// A static method that routes errors to a single centralized error-handler.
 /// This method will attempt to extract a human-readable error from the response string,
 /// based on the the format of the data and the error handling scheme of the service.
 /// </summary>
 public static ActionResult ShowErrorMessage(Office365ServiceInfo serviceInfo, string responseString)
 {
     string message, errorDetails;
     try
     {
         message = serviceInfo.ParseErrorMessage(responseString);
         errorDetails = responseString;
     }
     catch (Exception e)
     {
         message = "An unexpected error has occurred.";
         errorDetails = "Exception when parsing response string: " + e.ToString() +
             "\n\nResponse string was " + responseString;
     }
     return ShowErrorMessage(message, errorDetails);
 }
        /// <summary>
        /// Send an HTTP request, with authorization. If the request fails due to an unauthorized exception,
        ///     this method will try to renew the access token in serviceInfo and try again.
        /// </summary>
        public static async Task<HttpResponseMessage> SendRequestAsync(
            Office365ServiceInfo serviceInfo, HttpClient client, Func<HttpRequestMessage> requestCreator)
        {
            using (HttpRequestMessage request = requestCreator.Invoke())
            {
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", serviceInfo.AccessToken);
                request.Headers.UserAgent.Add(new ProductInfoHeaderValue(AppPrincipalId, String.Empty));
                HttpResponseMessage response = await client.SendAsync(request);

                // Check if the server responded with "Unauthorized". If so, it might be a real authorization issue, or 
                //     it might be due to an expired access token. To be sure, renew the token and try one more time:
                if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    Office365Cache.GetAccessToken(serviceInfo.ResourceId).RemoveFromCache();
                    serviceInfo.AccessToken = GetAccessTokenFromRefreshToken(serviceInfo.ResourceId);

                    // Create and send a new request:
                    using (HttpRequestMessage retryRequest = requestCreator.Invoke())
                    {
                        retryRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", serviceInfo.AccessToken);
                        retryRequest.Headers.UserAgent.Add(new ProductInfoHeaderValue(AppPrincipalId, String.Empty));
                        response = await client.SendAsync(retryRequest);
                    }
                }

                // Return either the original response, or the response from the second attempt:
                return response;
            }
        }