Introduction
I've been working in ASP.NET Web API where I bumped into some weird interactions when trying to call another API. I've tried 3 different ways to use HttpClient, all with different results.
Have tested everything using Postman, hence some results.
1. Sync HttpClient call
private static string GetAPI(string url)
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("x-api-key", "SomeSecretApiKey");
HttpResponseMessage response = client.GetAsync(url).Result;
string contents = response.Content.ReadAsStringAsync().Result;
if (response.IsSuccessStatusCode)
{
return contents;
}
}
return null;
}
Result
Does work, but I want to use async
2. Async httpClient call
private static async Task<string> GetAPI(string url)
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("x-api-key", "SomeSecretApiKey");
HttpResponseMessage response = await client.GetAsync(url);
string contents = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
return contents;
}
}
return null;
}
Result
Does not work. Will not go beyond the line HttpResponseMessage response = await client.GetAsync(url);
, since there's never a response?
3. Async httpClient call with shared HttpClient
private static readonly HttpClient client = new HttpClient();
private static async Task<string> GetAPI(string url)
{
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("x-api-key", "SomeSecretApiKey");
HttpResponseMessage response = await client.GetAsync(url);
string contents = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
return contents;
}
return null;
}
Result
Does work once. Will then throw the error: System.AggregateException: One or more errors occurred. ---> System.InvalidOperationException: This instance has already started one or more requests. Properties can only be modified before sending the first request.
(as suggested by this SO answer).
Question
I would appreciate it if someone could explain why these results are so different and/or give an alternative way to make a basic HttpClient
call (still would like to use async
).