来自PCL的Xamarin WebAPI电话

时间:2017-06-06 14:04:00

标签: c# asp.net-web-api xamarin async-await dotnet-httpclient

我正在尝试开发一个Xamarin.Forms或Xamarin.iOS / Xamarin.Droid本机应用程序,它可以对我的服务器进行Web API调用。我收到错误说HttpRequestException抛出。一旦我搜索了解决方案,就说它是因为它无法到达套接字,但我无法将其安装到PCL项目中。所以我检查了解决方案,他们说使用代理来达到服务。

这是我的问题。我已经尝试在PCL中创建一个代理连接到.Droid或.iOS项目中的服务,以便他们可以使用套接字,(虽然我不认为该服务应该在应用程序项目本身,因为重复的代码)。但代理类无法引用该服务,因为它不在项目中。

这是我的RestService课程。

public class RestService : IRestService
{
    private const string BASE_URI = "http://xxx.xxx.xxx.xxx/";
    private HttpClient Client;
    private string Controller;

    /**
     * Controller is the middle route, for example user or account etc.
     */
    public RestService(string controller)
    {
        Controller = controller;
        Client = new HttpClient();
    }

    /**
     * uri in this case is "userId?id=1".
     */
    public async Task<string> GET(string uri)
    {
        try
        {
            Client.BaseAddress = new Uri(BASE_URI);
            Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var fullUri = String.Format("api/{0}/{1}", Controller, uri);
            var response = Client.GetAsync(fullUri);
            string content = await response.Result.Content.ReadAsStringAsync();
            return content;
        }
        catch (Exception e)
        {
            return null;
        }
    }
}

我无法在网上找到任何有关如何使其发挥作用的好教程,我们将非常感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:2)

您正在混合async / await和阻止调用.Result

public async Task<string> GET(string uri) {
    //...other code removed for brevity

    var response = Client.GetAsync(fullUri).Result;

    //...other code removed for brevity
}

导致死锁导致您无法进入套接字。

使用async / await时,您需要始终保持异步,并避免阻止.Result.Wait()等来电。

public async Task<string> GET(string uri) {
    try {
        Client.BaseAddress = new Uri(BASE_URI);
        Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        var fullUri = String.Format("api/{0}/{1}", Controller, uri);
        var response = await Client.GetAsync(fullUri);
        var content = await response.Content.ReadAsStringAsync();
        return content;
    } catch (Exception e) {
        return null;
    }
}