客户端调用Web API等待

时间:2014-05-29 05:05:09

标签: c# asp.net-web-api

我有一个调用WebAPI服务的httpclient。 GET到达服务并返回内容,但客户端只是在等待......

客户代码:

    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代码:

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)
        };
    }
}

思想?

3 个答案:

答案 0 :(得分:2)

在您的客户端代码(无论最终调用RunAsyncGet)中,某些代码正在调用Task.WaitTask<T>.Result。那将cause a deadlock if called from the UI thread,正如我在博客上解释的那样。

正确的解决方案是将Wait / Result更改为使用await

答案 1 :(得分:1)

这就是我最终调用Web API的方式:

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
    }
}

答案 2 :(得分:0)

似乎您对EnsureSuccessStatusCode的致电可能是罪魁祸首。该方法实际上返回一个HttpResponseMessage,它将具有200范围内的HTTP状态,或者将引发异常。所以,你可能想要这样的东西:

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 ...
}