I have a .net project that is communicating with a backend java server (REST) for all related business operations. I am using HttpClient to send my requests. My problem lies in this: If a request fails, ie an AggregateException is raised from the .Result with 'a task was cancelled' in almost all the rest calls to the server my HttpClient instance loses the Accept and Accept-Language DefaultRequestHeaders. I have tried many different variations in the way I am instantiating the client, either as a static class or through the webconfig but it happens in all cases and i have no ideas left. Please see code below. I load from my web.Config the properties and this is my object which gets filled out correctly (got it from here):
public sealed class AthenaHttpClients : ConfigurationSection
{
private HttpClient _client { get; set; }
[ConfigurationProperty("athenaFactoryClient", IsRequired = true)]
public AthenaFactoryHttpClient FactoryClient
{
get { return (AthenaFactoryHttpClient)base["athenaFactoryClient"]; }
set { base["athenaFactoryClient"] = value; }
}
private static AthenaHttpClients instance = null;
public static HttpClient GetClient()
{
if (instance == null)
{
instance = (AthenaHttpClients)WebConfigurationManager.GetSection("athenaHttpClients");
}
instance.FactoryClient.Client = HttpClientFactory.Create(new CustomDelegatingHandlerTokenRefresher());
instance.FactoryClient.Client.BaseAddress = new Uri(ConfigurationManager.AppSettings["uri"]);
instance.FactoryClient.Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(instance.FactoryClient.HeaderValue));
instance.FactoryClient.Client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue(instance.FactoryClient.Language));
instance.FactoryClient.Client.DefaultRequestHeaders.Remove("Authorization");
return instance.FactoryClient.Client;
}
}
public class AthenaFactoryHttpClient : ConfigurationElement
{
[ConfigurationProperty("headerValue", IsRequired = true)]
public string HeaderValue
{
get { return (string)base["headerValue"]; }
set { base["headerValue"] = value; }
}
[ConfigurationProperty("language", IsRequired = true)]
public string Language
{
get { return (string)base["language"]; }
set { base["language"] = value; }
}
public HttpClient Client { get; set; }
}
}
I am calling my client like this:
private HttpClient client = AthenaHttpClients.GetClient();
and this is one of my calls to the backend server:
internal HttpResponseMessage getStudyContract(string id)
{
try
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", (string)HttpContext.Current.Session["accessToken"]);
HttpResponseMessage response = client.GetAsync(restEndpoint + restStudyContractsEndpoint + "/" + id).Result;
return response;
}
catch (AggregateException ex)
{
throw new RestHttpClientRequestException(restRequestExceptionMessage, ex.StackTrace);
}
catch (Exception ex)
{
throw new RestHttpClientRequestException(ex.Message, ex.StackTrace);
}
}
(I know it's not the best implementation using the async methods with the .Result, but for now it is ok). I force my request to getStudyContract() to fail by sending an Id with empty string. I then get the AggregateException and then all subsequent calls to my client simply lose the Accept and Accept-Language. I don't know what I am doing wrong. If anyone has a suggestion, please help!