MvvmCross - 从View模型调用Web服务

SPA*_*per 4 c# xamarin.ios xamarin.android mvvmcross

我是MvvmCross和Android开发的新手.我需要在视图模型中调用POST数据到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());
  }
}
Run Code Online (Sandbox Code Playgroud)

在我的View(UI)代码中,我为事件添加了一个事件处理程序Service_Finished.我注意到我可以CallService在视图模型中成功地从" "方法中抛出事件.但是,如果我尝试Service_Finished从部分ServiceBeginGetRequestStreamCallbackService_Completed部分触发,则事件永远不会在UI中触发.

由于视图模型位于可移植类库中,我无法弄清楚如何调试它.此时我知道CallService已成功调用.但是,我不知道自己到底在哪里ServiceBeginGetRequestStreamCallback,如果我到了Service_Completed.

我从Windows Phone开发经验中了解到,我需要检查一下我是否在UI线程上,如果没有,我必须做一些Deployment.stuff.但是,使用MvvmCross方法,我不确定a)我是否必须这样做; b)如果这是一个选项,因为视图模型应该适用于Android和iOS.无论如何,必须有一种方法来a)从视图模型调用Web服务,以及b)将消息发送回视图,以便可以更新UI.不幸的是,我似乎无法弄明白.有人(slodge :))能告诉我我做错了什么吗?

谢谢

Stu*_*art 9

通常,我将这种WebService调用放在Model而不是ViewModel中 - 它使ViewModel和WebService客户端代码更加可重用.

一些简单的例子是:

我从Windows Phone开发经验中了解到,我需要检查一下我是否在UI线程上,如果没有,我必须做一些Deployment.stuff.但是,使用MvvmCross方法,我不确定a)我是否必须这样做

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

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

MvvmCross提供了一个接口,允许您将执行编组到UI线程上.在ViewModel中,通过调用可以轻松完成InvokeOnMainThread(() => { /* your code */ })

在幕后,MvvmCross也将把所有RaisePropertyChanged执行都编组到UI线程中.注意 - 虽然ObservableCollection更新不是自动编组的 - 这是因为ObservableCollection是一个存在于MvvmCross之外的类.

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

查看样品(上图)

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

通常,您不应通过事件发送这些类型的消息.

相反,你应该:

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