Gina Marano
Gina Marano

Reputation: 1803

Client calling WebAPI stuck in await

I have a httpclient that is calling a WebAPI service. The GET reaches the service and returns the content but the client just keeps waiting...

Client code:

    static async Task RunAsyncGet(string baseUri, string uri)
    {
        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri(baseUri);
            HttpResponseMessage response = await client.GetAsync(uri); // <-- stuck here

            response.EnsureSuccessStatusCode();

            if (response.IsSuccessStatusCode)
            {
                IEnumerable<UserAccountModel> users = await response.Content.ReadAsAsync<IEnumerable<UserAccountModel>>();
                //...
            }
        }
    }

WebAPI code:

public class UserAccountController : ApiController
{
    private IRepository _repo;

    public UserAccountController(IRepository repo)
    {
        _repo = repo;
    }

    public HttpResponseMessage Get()
    {
        var s = _repo.GetAllUserAccounts();

        IContentNegotiator negotiator = Configuration.Services.GetContentNegotiator();
        ContentNegotiationResult result = negotiator.Negotiate(typeof(AuthResponseModel), Request, Configuration.Formatters);

        var bestMatchFormatter = result.Formatter;
        var mediaType = result.MediaType.MediaType;

        return new HttpResponseMessage()
        {
            StatusCode = HttpStatusCode.OK,
            Content = new ObjectContent<IQueryable<UserAccount>>(s, bestMatchFormatter, mediaType)
        };
    }
}

Thoughts?

Upvotes: 2

Views: 4130

Answers (3)

Gina Marano
Gina Marano

Reputation: 1803

This is how I ended up calling the WebAPI:

using (HttpClient client = new HttpClient())
{
    client.BaseAddress = new Uri("http://localhost:23302");
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    HttpResponseMessage response = client.GetAsync("api/useraccount").Result;
    if (response.IsSuccessStatusCode)
    {
        var t = response.Content.ReadAsAsync<IEnumerable<UserAccount>>().Result;
        ...
    }
    else
    {
        //Something has gone wrong, handle it here
    }
}

Upvotes: 1

Stephen Cleary
Stephen Cleary

Reputation: 456322

Further up in your client code (whatever ends up calling RunAsyncGet), some code is calling Task.Wait or Task<T>.Result. That will cause a deadlock if called from the UI thread, as I explain on my blog.

The proper solution is to change that Wait/Result to use await.

Upvotes: 2

Tieson T.
Tieson T.

Reputation: 21191

It seems that your call to EnsureSuccessStatusCode is the likely culprit. That method actually returns a HttpResponseMessage that will have a HTTP status in the 200 range, or will throw an exception. So, you probably want something like:

static async Task RunAsyncGet(string baseUri, string uri)
{
    var client = new HttpClient();

    client.BaseAddress = new Uri(baseUri);
    HttpResponseMessage response = await client.GetAsync(uri);

    IEnumerable<UserAccountModel> users = await response.EnsureSuccessStatusCode().Content.ReadAsAsync<IEnumerable<UserAccountModel>>();

    // ... the rest ...
}

Upvotes: 0

Related Questions