Reputation: 3
I have created two projects in a same solution, one for mvc application and other for web api.
When i am calling my web api method from PostMan or any HttpClient, i am able to receive the response as expected.
However when i am calling the same method in MVC application, the application keeps on running with no response received. No specific exceptions are logged or displayed by visual studio.
I have copied the code which i am using for reference. Any help will be highly appreciated.
public class UserFacade
{
HttpClient _client;
string url = "http://localhost:50759/api/v1/login";
public void LoginUser(string userName, string password)
{
_client = new HttpClient
{
BaseAddress = new Uri(url)
};
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var model = new UserModel
{
UserName = userName,
UserPassword = password
};
var userModel = JsonConvert.SerializeObject(model);
var content = new StringContent(userModel, Encoding.UTF8, "application/json");
GetUserTask(_client, content).Wait();
}
private async Task GetUserTask(HttpClient client, StringContent content)
{
using (client)
{
HttpResponseMessage res = await client.PostAsync(url, content);
res.EnsureSuccessStatusCode();
if (res.IsSuccessStatusCode)
{
var response = await res.Content.ReadAsStringAsync();
JavaScriptSerializer JSserializer = new JavaScriptSerializer();
//deserialize to your class
//var userResponse = JSserializer.Deserialize<UserResponse>(response);
}
}
}
}
Just for the information that i have made two startup projects in the solution and running the code from there.
Upvotes: 0
Views: 152
Reputation: 1039398
You are deadlocking yourself. Make sure that you do not capture the context when making the async calls:
private async Task GetUserTask(HttpClient client, StringContent content)
{
using (client)
{
HttpResponseMessage res = await client.PostAsync(url, content).ConfigureAwait(false);
res.EnsureSuccessStatusCode();
if (res.IsSuccessStatusCode)
{
var response = await res.Content.ReadAsStringAsync().ConfigureAwait(false);
}
}
}
Notice the .ConfigureAwait(false)
that I have added to both your async calls.
This being said, it is a complete waste to be making an asynchronous call and then blocking it like this:
GetUserTask(_client, content).Wait();
You are killing absolutely all the benefits of asynchronous calls. I would very strongly recommend you using the async version of the code:
public async Task LoginUser(string userName, string password)
{
_client = new HttpClient
{
BaseAddress = new Uri(url)
};
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var model = new UserModel
{
UserName = userName,
UserPassword = password
};
var userModel = JsonConvert.SerializeObject(model);
var content = new StringContent(userModel, Encoding.UTF8, "application/json");
await GetUserTask(_client, content);
}
and then of course have an async action controller action which will consume the async method:
public async Task<ActionResult> Index()
{
await new UserFacade().LoginUser("user", "secret");
return View();
}
Upvotes: 1