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

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

问题描述

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

在我的View(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.不幸的是,我似乎无法弄清楚.有人(住:)可以告诉我我做错了什么吗?

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.

以下是一些简单的示例:

Some simple examples of this are in:

  • the twittersearch sample - https://github.com/slodge/MvvmCross/tree/v3/Sample%20-%20TwitterSearch
  • the Dilbert sample - https://github.com/slodge/MvvmCross-Tutorials/tree/master/DailyDilbert

我从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天全站免登陆