【问题标题】:Xamarin Forms - calling rest service from viewmodel of pclXamarin Forms - 从 pcl 的视图模型调用休息服务
【发布时间】:2017-06-08 07:54:20
【问题描述】:

我创建了一个连接到 API 的类,以使用 httpclient 检索所需的数据。该文件在视图的代码隐藏文件中被调用并且运行良好。然后我决定实施 MVVM 方法。结果,我将初始化其余服务类的代码移到了视图模型中。 之后,我停止获取数据。为了进行调查,我在调试会话中声明了带有断点的调试会话,该断点位于我初始化其余服务类的行。比我执行那条线。通过这样做,我发现抛出了一个巨大的 android 单声道异常,并且如果停止了调试会话。应用退出调试会话。 自从我声明在 Xamarin Forms 中开发我的应用程序以来,这是第一次发生。我不知道它为什么会这样坏。对你的帮助表示感谢。

这是正常工作的代码。 在文件后面的视图代码中

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SubtaskPage : ContentPage
{
    protected override void OnAppearing()
    {
         base.OnAppearing();
         PopulateSubtaskData();
    }
    private async void PopulateSubtaskData()
    {
        lstSubtasks.IsRefreshing = true;
        try
        {
            RestService rs = new RestService();
            SResponse = await rs.GetSubtasksAsync(Convert.ToInt32(Application.Current.Properties["UserId"]));
            if (SResponse.Status == 1)
            {
                lstSubtasks.ItemsSource = SResponse.Subtasks;
            }
            else
            {
                await DisplayAlert("Error", SResponse.Message, "Ok");
            }
       }
       catch (Exception E)
       {
           Debug.WriteLine(@"GetSubtasksAsync -> ERROR {0}", E.Message);
       }
       lstSubtasks.IsRefreshing = false;
    }
}

其余服务类如下 此类位于名为“服务”的单独文件夹中。出于安全原因,已更改 ip 和 url。

class RestService
{
        HttpClient client;
        public List<Ticket> Tickets { get; private set; }
        string Server1 = "server ip";
        string Server2 = "server ip";
        public RestService()
        {
            client = new HttpClient();
            client.MaxResponseContentBufferSize = 256000;
        }
        public async Task<SubtasksResponse> GetSubtasksAsync(int UserId)
        {
            SubtasksResponse SubtaskResponse = new SubtasksResponse();
            string ApiUrl = "URL";
            string Url = "";
            HttpResponseMessage response;
            if (CrossConnectivity.Current.IsConnected)
            {
                Url = await GetActiveServerAsync();
                if (Url != "")
                {
                    var uri = string.Format(Url + ApiUrl, UserId);
                    try
                    {
                        response = await client.GetAsync(uri);
                        if (response.IsSuccessStatusCode)
                        {
                            var content = await response.Content.ReadAsStringAsync();
                            SubtaskResponse.Subtasks = JsonConvert.DeserializeObject<List<Ticket>>(content);
                            SubtaskResponse.Status = 1;
                        }
                        else
                        {
                            SubtaskResponse.Subtasks = null;
                            SubtaskResponse.Status = 0;
                            SubtaskResponse.Message = "Attempt to fetch data from server was unsuccessful. Please try again";
                        }
                    }
                    catch (Exception E)
                    {
                        SubtaskResponse.Subtasks = null;
                        SubtaskResponse.Status = 0;
                        SubtaskResponse.Message = "Error occured while fetching data from the server. Please try again";
                    }
                }
                else
                {
                    SubtaskResponse.Subtasks = null;
                    SubtaskResponse.Status = 0;
                    SubtaskResponse.Message = "Remote Server Not Responding! Please try again later";
                }
            }
            else
            {
                SubtaskResponse.Subtasks = null;
                SubtaskResponse.Status = 0;
                SubtaskResponse.Message = "No Network Connection Found! Please connect to a network and try again";
            }
            return SubtaskResponse;
        }
    }
}

在我将视图模型添加到组合中之前,这一切正常。 这就是我在视图模型中调用函数的方式。

async Task<SubtasksResponse> PopulateSubtaskList()
{
    RestService rs = new RestService();
    IsBusy = true;
    _subtaskList = await rs.GetSubtasksAsync(Convert.ToInt32(Application.Current.Properties["UserId"]));
    IsBusy = false;
    return _subtaskList;
}

"RestService rs = new RestService();"这是代码中断的那一行。

这是代码中断时发生的异常的图像。

希望您能清楚地了解情况。如果需要其他信息,请告诉我。 谢谢

【问题讨论】:

  • 如果您可以共享代码,无论您到目前为止尝试过什么,都很棒。以便该社区可以更好地帮助您。
  • 需要将产生异常的代码和异常本身添加到您的问题中
  • 为 API 调用创建单独的文件夹,如“服务”并在此处调用 api。
  • ViewModel 是否在单独的 pcl 项目中?

标签: xamarin mvvm xamarin.forms httpclient viewmodel


【解决方案1】:

不要这样做。如果您想从 mvvm Xamarin Forms 应用程序调用 rest,我可以建议 Refit。所有困难的工作都已经为你完成并抽象出来了。只需几行代码,您就可以启动并运行。

【讨论】:

  • 我使用的 API 是用 PHP 编写的。
  • 只要是可以使用 refit 的休息服务,你调用的 api 是用什么编写的都没有关系
【解决方案2】:

顺便说一句,您显示的错误消息可能与您的代码无关,而是最近 Xamarin 版本中的错误。见这里:https://bugzilla.xamarin.com/show_bug.cgi?id=56787

【讨论】:

  • xamarin 表单中的问题仍未解决
  • 此问题已通过此link 中给出的解决方案得到解决。上面给出的 bugzilla 链接中提到了这一点。
【解决方案3】:

在此页面 (https://releases.xamarin.com/common-issues-in-the-xamarin-15-2-2-release-being-tracked-by-the-xamarin-team/) 上找到了答案。

解决方法如下

  1. 下载缺少的Mono.Posix 文件并解压缩存档。
  2. 在资源管理器中右键单击 Mono.Posix.dll 文件并选择属性。
  3. 检查“数字签名”选项卡以确保文件显示有效的 Xamarin Inc. 签名。
  4. 在“常规”选项卡的底部,如果出现“取消阻止”复选框,请启用它并选择“确定”。 (此复选框的显示取决于文件的下载方式。)
  5. 对于 Visual Studio 2017,将 Mono.Posix.dll 文件复制到“Xamarin.VisualStudio”扩展目录中。例如,对于企业版的默认安装,将文件复制到: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\Extensions\Xamarin.VisualStudio
  6. 对于 Visual Studio 2015,将文件复制到“Xamarin\Xamarin”扩展目录中: C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Xamarin\Xamarin\
  7. 退出并重新启动 Visual Studio。

更多详情,请访问上面给出的链接。

【讨论】:

    猜你喜欢
    • 2020-06-20
    • 2017-08-25
    • 2017-07-26
    • 2017-04-08
    • 2014-09-08
    • 2017-05-18
    • 1970-01-01
    • 1970-01-01
    • 2016-10-08
    相关资源
    最近更新 更多