Xamarin表单-从pcl的viewmodel调用rest服务

Xamarin表单-从pcl的viewmodel调用rest服务,xamarin,mvvm,xamarin.forms,httpclient,viewmodel,Xamarin,Mvvm,Xamarin.forms,Httpclient,Viewmodel,我创建了一个连接到API的类,以使用httpclient检索所需的数据。该文件在视图的代码隐藏文件中被调用,并且工作得非常好。然后我决定实现MVVM方法。因此,我将初始化rest服务类的代码移到了视图模型中。 这样做之后,我停止获取数据。为了进行调查,我在调试会话中声明了断点,断点位于初始化rest服务类的行上。然后我执行了那句话。通过这样做,我发现一个巨大的android mono异常被抛出,调试会话被停止。应用程序退出调试会话。 自从我声明用Xamarin表单开发我的应用程序以来,这还是第一

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

这是正常工作的代码。 在查看代码隐藏文件中

[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;
        }
    }
}
类RestService
{
HttpClient;
公共列表票证{get;private set;}
字符串Server1=“服务器ip”;
字符串Server2=“服务器ip”;
公共服务()
{
client=新的HttpClient();
client.MaxResponseContentBufferSize=256000;
}
公共异步任务GetSubtasksAsync(int UserId)
{
SubtasksResponse SubtasksResponse=新的SubtasksResponse();
字符串apirl=“URL”;
字符串Url=“”;
HttpResponseMessage响应;
if(交叉连接.当前.断开连接)
{
Url=等待GetActiveServerAsync();
如果(Url!=“”)
{
var uri=string.Format(Url+ApiUrl,UserId);
尝试
{
response=wait client.GetAsync(uri);
if(响应。IsSuccessStatusCode)
{
var content=await response.content.ReadAsStringAsync();
SubtaskResponse.Subtasks=JsonConvert.DeserializeObject(内容);
子任务响应状态=1;
}
其他的
{
SubtaskResponse.Subtasks=null;
子任务响应状态=0;
SubtaskResponse.Message=“尝试从服务器获取数据失败。请重试”;
}
}
捕获(例外E)
{
SubtaskResponse.Subtasks=null;
子任务响应状态=0;
SubtaskResponse.Message=“从服务器获取数据时出错。请重试”;
}
}
其他的
{
SubtaskResponse.Subtasks=null;
子任务响应状态=0;
SubtaskResponse.Message=“远程服务器没有响应!请稍后再试”;
}
}
其他的
{
SubtaskResponse.Subtasks=null;
子任务响应状态=0;
SubtaskResponse.Message=“未找到网络连接!请连接到网络并重试”;
}
返回子任务响应;
}
}
}
在我将视图模型添加到混合中之前,这一切都很正常。 这就是我在视图模型中调用函数的方式

async Task<SubtasksResponse> PopulateSubtaskList()
{
    RestService rs = new RestService();
    IsBusy = true;
    _subtaskList = await rs.GetSubtasksAsync(Convert.ToInt32(Application.Current.Properties["UserId"]));
    IsBusy = false;
    return _subtaskList;
}
async Task PopulateSubtaskList()
{
RestService rs=新的RestService();
IsBusy=true;
_subtaskList=wait rs.GetSubtasksAsync(Convert.ToInt32(Application.Current.Properties[“UserId]”));
IsBusy=false;
返回子任务列表;
}
“RestService rs=new RestService();”这是代码中断的行

下面是代码中断时发生的异常的图像

希望你能清楚地了解情况。如果需要更多信息,请告诉我。
谢谢,不要这样做。如果您想从mvvm Xamarin表单应用程序调用rest,我可以提供建议。所有困难的工作都已经为你完成了,并被抽象掉了。您只需要几行代码就可以启动并运行。

顺便说一句,您显示的错误消息可能与您的代码无关,但在最近的Xamarin版本中是一个bug。请参见此处:

在此页上找到了答案()

解决办法如下

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

  • 有关更多详细信息,请访问上面给出的链接。

    如果您可以共享代码,无论您到目前为止尝试过什么,那就太好了。因此,社区可以更好地帮助您。需要添加生成异常的代码和异常本身