Get ASP.NET MVC5 WebAPI token fails sometimes
Code
string GetAPITokenSync(string username, string password, string apiBaseUri)
It's hard to say for certain, but the way you're blocking HttpClient calls can't be helping. HttpClient is an async-only library; you may have a deadlock situation. I suggest getting rid of all .Result
s and .Wait()
s and write everything asynchronously, using async/await
. And your Task.Run is achieving nothing, so that should go.
I understand this is Topshelf app ported over from a console app. I'm not very familiar with Topshelf, but I assume that, like console apps, you need to block somewhere or your app will simply exit. The place to do that is at the very top - the entry point of the app.
This demonstrates the pattern, along with a re-write of your GetApiToken
method:
// app entry point - the only place you should block
void Main()
{
MainAsync().Wait();
}
// the "real" starting point of your app logic. do everything async from here on
async Task MainAsync()
{
...
var token = await GetApiTokenAsync(username, password, apiBaseUri);
...
}
async Task GetApiTokenAsync(string username, string password, string apiBaseUri)
{
var token = string.Empty;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(apiBaseUri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.Timeout = TimeSpan.FromSeconds(60);
//setup login data
var formContent = new FormUrlEncodedContent(new[]
{
new KeyValuePair("grant_type", "password"),
new KeyValuePair("username", username),
new KeyValuePair("password", password),
});
//send request
HttpResponseMessage responseMessage = await client.PostAsync("/Token", formContent);
var responseJson = await responseMessage.Content.ReadAsStringAsync();
var jObject = JObject.Parse(responseJson);
token = jObject.GetValue("access_token").ToString();
return token;
}
}