MvvmCross - 从视图模型调用 Web 服务 [英] MvvmCross - Calling Web Service from View Model

查看:19
本文介绍了MvvmCross - 从视图模型调用 Web 服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm new to MvvmCross and Android development. I have a need to call to POST data to a JSON web service in my view model. I then need to display the result of the web service back in my UI. The gist of my view model looks like the following:

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 中触发该事件.

In my View (UI) code, I've added an event-handler for the Service_Finished event. I've noticed that I can successfully throw the event from the "CallService" method in my view model. However, if I try to fire Service_Finished from either the ServiceBeginGetRequestStreamCallback or the Service_Completed portions, the event is never fired in the UI.

由于视图模型在可移植的类库中,我无法弄清楚如何调试它.此时我知道 CallService 被成功调用.但是,我无法确定我在 ServiceBeginGetRequestStreamCallback 中的哪个位置,以及我是否甚至进入了 Service_Completed.

Due to the fact that the view model is in a portable class library, I can't figure out how to debug this. At this point I know that CallService is getting successfully called. However, I can't tell where I'm getting within ServiceBeginGetRequestStreamCallback and if I'm even getting to Service_Completed.

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

I know from my Windows Phone dev experience, I would need to check to see if I'm on the UI thread, if not, I'd have to do some Deployment.stuff. But, with the MvvmCross approach, I'm not sure a) if I have to do that and b) if that is even an option since the view model should work with both Android and iOS. Regardless, there has to be a way to a) call a web service from a view model and b) send a message back to the view so that the UI can be updated. Unfortunately, I can't seem to figure it out. Can someone (slodge :)) tell me what I'm doing wrong?

谢谢

推荐答案

一般来说,我将这种 WebService 调用放在 Model 而不是 ViewModel 中——它使 ViewModel 和 WebService 客户端代码的可重用性更高.

In general, I put this kind of WebService call in the Model rather than in the ViewModel - it makes both the ViewModel and the WebService client code much more reusable.

一些简单的例子在:

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

I know from my Windows Phone dev experience, I would need to check to see if I'm on the UI thread, if not, I'd have to do some Deployment.stuff. But, with the MvvmCross approach, I'm not sure a) if I have to do that and

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

Yes, all communication from ViewModel->View should be on the UI thread.

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

b) if that is even an option since the view model should work with both Android and iOS.

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

MvvmCross provides an interface to allow you to marshal execution onto the UI thread. In a ViewModel, this is easily done by calling InvokeOnMainThread(() => { /* your code */ })

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

Behind the scenes, MvvmCross will also marshall all RaisePropertyChanged executions to the UI thread too. Note - that ObservableCollection updates are not automatically marshalled though - this is because ObservableCollection is a class that exists outside of MvvmCross.

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

Regardless, there has to be a way to a) call a web service from a view model and

查看示例(上图)

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

b) send a message back to the view so that the UI can be updated.

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

In general you should not send these type of messages via events.

相反,您应该:

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

这篇关于MvvmCross - 从视图模型调用 Web 服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆