Xamarin WebAPI从PCL调用

9 浏览
0 Comments

Xamarin WebAPI从PCL调用

我正在尝试开发一个能够调用我的服务器的Web API的Xamarin.Forms或Xamarin.iOS/Xamarin.Droid本机应用程序。我遇到了一个名为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是中间路径,例如user或account等。
     */
    public RestService(string controller)
    {
        Controller = controller;
        Client = new HttpClient();
    }
    /**
     * 在这种情况下,uri是"userId?id=1"。
     */
    public async Task 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;
        }
    }
}

我在网上找不到任何好的教程,教我如何使其正常工作,如果有任何帮助,将不胜感激。

0
0 Comments

问题的原因是代码中混合了异步/等待和阻塞调用.Result。这导致了死锁,无法访问套接字。在使用异步/等待时,需要完全使用异步,并避免阻塞调用,如.Result.Wait()

解决方法是去掉.Result,使用await关键字进行异步操作。具体代码如下:

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

0