Amit Gupta
Amit Gupta

Reputation: 3

Webapi call from mvc application

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

Answers (1)

Darin Dimitrov
Darin Dimitrov

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

Related Questions