C# MvvmCross-从视图模型调用Web服务

C# MvvmCross-从视图模型调用Web服务,c#,xamarin.ios,xamarin.android,mvvmcross,C#,Xamarin.ios,Xamarin.android,Mvvmcross,我是MvvmCross和Android开发的新手。我需要调用将数据发布到视图模型中的JSON web服务。然后,我需要在UI中显示web服务的结果。我的视图模型的要点如下所示: public class MyViewModel : MvxViewModel { public override void Start() { base.Start(); } public event EventHandler<EventArgs> Service_Finished

我是MvvmCross和Android开发的新手。我需要调用将数据发布到视图模型中的JSON web服务。然后,我需要在UI中显示web服务的结果。我的视图模型的要点如下所示:

public class MyViewModel : MvxViewModel
{
  public override void Start()
  {
    base.Start();
  }

  public event EventHandler<EventArgs> Service_Finished;
  public void CallService()
  {
    string url = GetServiceUrl();

    WebRequest serviceRequest = HttpWebRequest.Create(url);
    serviceRequest.Method = "POST";
    serviceRequest.ContentType = "application/json";
    serviceRequest.BeginGetRequestStream(new AsyncCallback(ServiceBeginGetRequestStreamCallback), serviceRequest);
  }

  private void ServiceBeginGetRequestStreamCallback(IAsyncResult ar)
  {
    string json = GetJson();

    HttpWebRequest myWebRequest = (HttpWebRequest)(ar.AsyncState);
    using (Stream postStream = myWebRequest.EndGetRequestStream(ar))
    {
      byte[] byteArray = Encoding.UTF8.GetBytes(json);
      postStream.Write(byteArray, 0, byteArray.Length);
    }
    myWebRequest.BeginGetResponse(new AsyncCallback(Service_Completed), myWebRequest);
  }

  private void Service_Completed(IAsyncResult result)
  {
    if (Service_Finished != null)
      Service_Finished(this, new EventArgs());
  }
}
公共类MyViewModel:MvxViewModel
{
公共覆盖无效开始()
{
base.Start();
}
公共事件事件处理程序服务\u已完成;
公用呼叫服务()
{
字符串url=GetServiceUrl();
WebRequestServiceRequest=HttpWebRequest.Create(url);
serviceRequest.Method=“POST”;
serviceRequest.ContentType=“应用程序/json”;
serviceRequest.BeginGetRequestStream(新的异步回调(ServiceBeginGetRequestStreamCallback),serviceRequest);
}
私有void ServiceBeginGetRequestStreamCallback(IAsyncResult ar)
{
字符串json=GetJson();
HttpWebRequest myWebRequest=(HttpWebRequest)(ar.AsyncState);
使用(Stream postStream=myWebRequest.EndGetRequestStream(ar))
{
byte[]byteArray=Encoding.UTF8.GetBytes(json);
Write(byteArray,0,byteArray.Length);
}
myWebRequest.BeginGetResponse(新的异步回调(服务完成),myWebRequest);
}
私人作废服务完成(IAsyncResult结果)
{
如果(服务完成!=空)
服务_已完成(此,新事件args());
}
}
在我的视图(UI)代码中,我为
服务\u Finished
事件添加了一个事件处理程序。我注意到我可以从视图模型中的“
CallService
”方法成功地抛出事件。但是,如果我尝试从
ServiceBeginGetRequestStreamCallback
Service\u Completed
部分触发
Service\u Finished
,则该事件永远不会在UI中触发

由于视图模型位于一个可移植类库中,我不知道如何调试它。此时,我知道CallService正在被成功调用。但是,我不知道我在
ServiceBeginGetRequestStreamCallback中得到了什么,也不知道我是否得到了
Service\u Completed

我从我的Windows Phone开发经验中知道,我需要检查我是否在UI线程上,如果不是,我就必须做一些部署工作。但是,对于MvvmCross方法,我不确定a)是否必须这样做,b)这是否是一个选项,因为视图模型应该同时适用于Android和iOS。无论如何,必须有一种方法a)从视图模型调用web服务,b)将消息发送回视图,以便更新UI。不幸的是,我似乎无法理解。有人能告诉我我做错了什么吗


谢谢

总的来说,我将这种Web服务调用放在模型中,而不是放在ViewModel中-它使ViewModel和Web服务客户机代码都更加可重用

以下是一些简单的例子:

  • twittersearch示例-
  • Dilbert样本-
我从我的Windows Phone开发经验中知道,我需要检查我是否在UI线程上,如果不是,我就必须做一些部署工作。 但是,对于MvvmCross方法,我不确定 a) 如果我必须这么做

是的,来自ViewModel->View的所有通信都应该在UI线程上

b) 如果这是一个选项,因为视图模型应该同时适用于Android和iOS

MvvmCross提供了一个接口,允许您将执行封送到UI线程。在ViewModel中,通过调用
InvokeOnMainThread(()=>{/*您的代码*/})

在幕后,MvvmCross还将把所有
RaisePropertyChanged
执行也打包到UI线程注意-尽管如此,
ObservableCollection
更新不会自动编组-这是因为
ObservableCollection
是一个存在于MvvmCross之外的类

无论如何,必须有一种方法a)从视图模型调用web服务,并

见样本(如上)

b) 将消息发送回视图,以便更新UI

一般来说,您不应该通过事件发送这些类型的消息

相反,你应该:

  • 更新ViewModel属性
  • (偶尔)通过信使发送消息

非常感谢您的见解。像你这样的社区领袖帮助我学习和成长。