简体   繁体   English

MvvmCross - 从View模型调用Web服务

[英]MvvmCross - Calling Web Service from View Model

I'm new to MvvmCross and Android development. 我是MvvmCross和Android开发的新手。 I have a need to call to POST data to a JSON web service in my view model. 我需要在视图模型中调用POST数据到JSON Web服务。 I then need to display the result of the web service back in my UI. 然后,我需要在我的UI中显示Web服务的结果。 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());
  }
}

In my View (UI) code, I've added an event-handler for the Service_Finished event. 在我的View(UI)代码中,我为Service_Finished事件添加了一个事件处理程序。 I've noticed that I can successfully throw the event from the " CallService " method in my view model. 我注意到我可以在视图模型中从“ CallService ”方法成功抛出事件。 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. 但是,如果我尝试火灾Service_Finished无论从ServiceBeginGetRequestStreamCallbackService_Completed部分,该事件从未在UI解雇。

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. 此时我知道CallService已成功调用。 However, I can't tell where I'm getting within ServiceBeginGetRequestStreamCallback and if I'm even getting to Service_Completed . 但是,我无法分辨出我在ServiceBeginGetRequestStreamCallback以及我是否已进入Service_Completed

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. 我知道从我的Windows Phone开发经验中,我需要检查我是否在UI线程上,如果没有,我必须做一些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. 但是,使用MvvmCross方法,我不确定a)我是否必须这样做; b)如果这是一个选项,因为视图模型应该适用于Android和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. 无论如何,必须有一种方法来a)从视图模型调用Web服务并且b)将消息发送回视图以便可以更新UI。 Unfortunately, I can't seem to figure it out. 不幸的是,我似乎无法弄明白。 Can someone (slodge :)) tell me what I'm doing wrong? 有人(slodge :))能告诉我我做错了什么吗?

Thank you 谢谢

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

Some simple examples of this are in: 一些简单的例子是:

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. 我知道从我的Windows Phone开发经验中,我需要检查我是否在UI线程上,如果没有,我必须做一些Deployment.stuff。 But, with the MvvmCross approach, I'm not sure a) if I have to do that and 但是,使用MvvmCross方法,我不确定a)我是否必须这样做

Yes, all communication from ViewModel->View should be on the UI thread. 是的,来自ViewModel-> View的所有通信都应该在UI线程上。

b) if that is even an option since the view model should work with both Android and iOS. b)如果这是一个选项,因为视图模型应该适用于Android和iOS。

MvvmCross provides an interface to allow you to marshal execution onto the UI thread. MvvmCross提供了一个接口,允许您将执行编组到UI线程上。 In a ViewModel, this is easily done by calling InvokeOnMainThread(() => { /* your code */ }) 在ViewModel中,通过调用InvokeOnMainThread(() => { /* your code */ })可以轻松完成

Behind the scenes, MvvmCross will also marshall all RaisePropertyChanged executions to the UI thread too. 在幕后,MvvmCross还将把所有RaisePropertyChanged执行编组到UI线程中。 Note - that ObservableCollection updates are not automatically marshalled though - this is because ObservableCollection is a class that exists outside of MvvmCross. 注意 - ObservableCollection更新不会自动编组 - 这是因为ObservableCollection是一个存在于MvvmCross之外的类。

Regardless, there has to be a way to a) call a web service from a view model and 无论如何,必须有一种方法来a)从视图模型调用Web服务

See the samples (above) 查看样品(上图)

b) send a message back to the view so that the UI can be updated. b)将消息发送回视图,以便可以更新UI。

In general you should not send these type of messages via events. 通常,您不应通过事件发送这些类型的消息。

Instead, you should: 相反,你应该:

  • update ViewModel properties 更新ViewModel属性
  • (occasionally) send Messages via a Messenger (偶尔)通过Messenger发送消息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM