MvvmCross - 在视图模型中调用 Web 服务

4

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

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());
  }
}

在我的视图(UI)代码中,我为 Service_Finished 事件添加了一个事件处理程序。我注意到我可以成功地从我的视图模型的 "CallService" 方法中抛出该事件。然而,如果我尝试从 ServiceBeginGetRequestStreamCallbackService_Completed 部分触发 Service_Finished ,则该事件在 UI 中永远不会被触发。
由于视图模型位于便携式类库中,我无法弄清楚如何调试此问题。此时,我知道 CallService 被成功调用。但是,我无法确定我是否在 ServiceBeginGetRequestStreamCallback 中,并且我是否甚至到达了 Service_Completed
从我的 Windows Phone 开发经验中,我知道我需要检查是否在 UI 线程上,如果没有,我需要做一些 Deployment.stuff。但是,使用 MvvmCross 方法,我不确定是否必须这样做,以及是否是一个选项,因为视图模型应该适用于 Android 和 iOS。无论如何,必须有一种方法 a) 从视图模型调用 Web 服务并 b) 发送消息回视图,以便可以更新 UI。不幸的是,我似乎无法弄清楚。可以有人(slodge :)) 告诉我我做错了什么吗?
谢谢
1个回答

9
一般来说,我会将这种WebService调用放在Model中,而不是ViewModel中 - 这使得ViewModel和WebService客户端代码都更加可重用。
一些简单的示例在以下位置:
- twittersearch示例 - https://github.com/slodge/MvvmCross/tree/v3/Sample%20-%20TwitterSearch - Dilbert示例 - https://github.com/slodge/MvvmCross-Tutorials/tree/master/DailyDilbert 我从我的Windows Phone开发经验中知道,我需要检查是否在UI线程上,如果不是,我需要进行一些Deployment工作。但是,使用MvvmCross方法,我不确定:
a) 我是否需要这样做;
是的,来自ViewModel->View的所有通信都应该在UI线程上进行。
b) 是否可以这样做,因为ViewModel应该适用于Android和iOS。
MvvmCross提供了一个接口,允许您将执行调度到UI线程。在ViewModel中,只需调用InvokeOnMainThread(() => { /* your code */ })即可轻松完成此操作。
在幕后,MvvmCross还会将所有RaisePropertyChanged执行调度到UI线程。请注意,ObservableCollection的更新不会自动调度 - 这是因为ObservableCollection是存在于MvvmCross之外的类。
尽管如此,仍然有一种方法可以a)从ViewModel调用Web服务,并b)向视图发送消息以便更新UI。通常情况下,不应通过事件发送这些类型的消息。
相反,您应该:
- 更新ViewModel属性 - (偶尔)通过Messenger发送消息

非常感谢您的见解。正是像您这样的社区领袖帮助我不断学习和成长。 - SPA Developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接