从视图模型交叉调用Web服务

本文关键字:调用 Web 服务 视图 模型 | 更新日期: 2023-09-27 18:10:13

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

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

由于视图模型是在一个可移植的类库,我不知道如何调试这一事实。此时,我知道CallService正在被成功调用。然而,我不知道我在ServiceBeginGetRequestStreamCallback内的位置,如果我甚至到达Service_Completed

我知道从我的Windows Phone开发经验,我需要检查,看看我是否在UI线程,如果不是,我必须做一些部署的东西。但是,使用MvvmCross方法,我不确定a)如果我必须这样做,b)如果这是一个选项,因为视图模型应该与Android和iOS一起工作。无论如何,必须有一种方法a)从视图模型调用web服务,b)向视图发送消息,以便UI可以更新。不幸的是,我似乎弄不明白。有人能告诉我我做错了什么吗?

谢谢

从视图模型交叉调用Web服务

一般来说,我把这种WebService调用放在Model中而不是ViewModel中——这使得ViewModel和WebService客户端代码更易于重用。

一些简单的例子如下:

  • twittersearch示例- https://github.com/slodge/MvvmCross/tree/v3/Sample%20-%20TwitterSearch
  • 呆伯特样本- https://github.com/slodge/MvvmCross-Tutorials/tree/master/DailyDilbert

我知道从我的Windows Phone开发经验,我需要检查,看看我是否在UI线程,如果不是,我必须做一些部署的东西。但是,对于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属性
  • (偶尔)通过信使发送消息