MvvmCross - 从视图模型调用 Web 服务 [英] MvvmCross - Calling Web Service from View Model
问题描述
我是 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
"方法成功抛出事件.但是,如果我尝试从 ServiceBeginGetRequestStreamCallback
或 Service_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.
一些简单的例子在:
- twittersearch 示例 - https://github.com/slodge/MvvmCross/tree/v3/Sample%20-%20TwitterSearch
- 呆伯特示例 - https://github.com/slodge/MvvmCross-教程/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屋!