来自 PCL 的 Xamarin WebAPI 调用

Posted

技术标签:

【中文标题】来自 PCL 的 Xamarin WebAPI 调用【英文标题】:Xamarin WebAPI call from PCL 【发布时间】:2017-06-06 14:03:59 【问题描述】:

我正在尝试开发一个 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;
        
    

我在网上找不到任何关于如何使它工作的好的教程,非常感谢这方面的任何帮助。

【问题讨论】:

你检查过这个-***.com/questions/15143107/…和这个-***.com/questions/31131658/xamarain-web-api 刚刚查看了两个链接。这两种解决方案都不是问题,因为我没有使用 IIS,并且给定的 url 适用于邮递员。 @Tomaltach 总体上避免阻塞呼叫。将其移至响应没有任何区别。它仍然是一个阻塞调用 你可以试试改装,在PCL里好用github.com/paulcbetts/refit 【参考方案1】:

您正在混合 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;
    

【讨论】:

抱歉混淆了代码行。在我在这里发布代码之前尝试了几种方法,结果有点混杂。我现在已经解决了这个问题,但由于套接字仍然失败。 @Tomaltach,因为您仍在使用阻塞呼叫。摆脱.Result。这导致了阻塞。

以上是关于来自 PCL 的 Xamarin WebAPI 调用的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin.Forms 中的 MVVMLight 的 EventToCommand

忽略 Xamarin.Forms (PCL) 中的 SSL 证书错误

使 PCL Xamarin (MonoDroid/MonoTouch) 兼容的问题

将文件下载进度从 PCL 更新到 Xamarin.Android

Xamarin PCL 库中的 GetConstructors

新的 PCL 项目不在 Mac/Xamarin 工作室上构建