Windows Phone 7下动态调用Web Service的异步实现
2010-12-23 13:55 by hackerzhou前两天写了篇关于.NET 2.0下如何不用Service References从而实现异步的动态Web Service调用。其实本来是写好之后看看是否能直接在Windows Phone 7上跑的,结果发现Win Phone下的Silverlight中的HttpWebRequest的用法有些独特,GetRequestStream和GetResponse都变成了异步操作,代码也需要做略微的调整。
代码链接如下:
1. CallCompletedEventArgs.cs
2. WebServicesUtil.cs
事件框架和上一篇差不多,差别如下:
1.由于GetRequestStream变成异步操作,因此需要在BeginCall的时候执行BeginGetRequestStream,定义一个回调函数(GetRequestStreamCallBack),指示得到了RequestStream了之后该进行的操作。
public void BeginCall(String method, Encoding encoding, params KeyValuePair<String, String>[] para)
{
if (ServiceUrl == null || method == null)
{
throw new Exception("Args Error!");
}
String url = ServiceUrl + "/" + method;
HttpWebRequest req = GetHttpWebRequest(url, "POST", Cookie);
if (para != null)
{
foreach (KeyValuePair<String, String> p in para)
{
buf.Append(p.Key + "=" + p.Value + "&");
}
}
req.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallBack), req);
}
2.得到了RequestStream后进入GetRequestStreamCallBack回调函数,往RequestStream里写入POST的数据,同时执行BeginGetResponse,并定义一个回调函数GetResponseStreamCallBack。
public void GetRequestStreamCallBack(IAsyncResult asyncResult)
{
HttpWebRequest req = (HttpWebRequest)asyncResult.AsyncState;
Stream requestStream = req.EndGetRequestStream(asyncResult);
using (StreamWriter writer = new StreamWriter(requestStream))
{
String str = buf.ToString();
//if (str.EndsWith("&"))
//{
// str = str.Substring(0, Math.Max(0, str.Length - 1));
//}
writer.Write(str);
writer.Flush();
}
req.BeginGetResponse(new AsyncCallback(GetResponseStreamCallBack), req);
}
3.在GetResponseStreamCallBack中得到了服务器返回的Response,触发事件,整个异步操作完成
public void GetResponseStreamCallBack(IAsyncResult asyncResult)
{
HttpWebRequest req = (HttpWebRequest)asyncResult.AsyncState;
WebResponse response = req.EndGetResponse(asyncResult);
using (Stream responseStream = response.GetResponseStream())
{
String result = GetStringFromStream(responseStream, Encoding);
XDocument rootDoc = GetXDocumentFromXmlString(result);
XDocument doc = GetXDocumentFromXmlString(HttpUtility.HtmlDecode(rootDoc.Root.Value));
CallCompletedEventArgs e = new CallCompletedEventArgs(doc, null, false, null);
if (CallCompleted != null)
{
CallCompleted(this, e);
}
}
}
需要说明的两点:
1.在回调事件中使用AsyncState来保存自己需要用到的对象。一开始我遇到了点困难,在于进入回调函数的时候,我拿不到原来的那个HttpWebRequest了,查了MSDN和网上的相关介绍,把HttpWebRequest在BeginGetRequestStream/BeginGetResponse的时候保存起来,在回调函数中可以通过AsyncState来获取保存的对象,执行相关的操作。
2.此例中由于GetRequestStream/GetResponse都是异步操作,而且GetResponse必须在GetRequestStream并且写入POST参数了以后调用,因此采用了回调函数中调用异步Begin操作的方法来实现两个异步操作捆绑成同步操作。
2014-06-05 17:34
楼主,现在wp8.1了,你发的这个还能用不?顺带求两份的完整版,我看过一个demo用了webclient类,但是不会用。以前我使用request.Headers[]设置http头,KeyValuePair是不是也是这个作用啊?现在我需要设置http头,还需要post一个string,请问大神该怎么做。新手,十分感谢
2014-02-10 18:25
楼主你好,能发一份动态调用webserivce的demo给我吗?
[email protected]
谢谢!
2013-12-31 10:11
楼主你好,能否发一份动态调用webserivce服务的demo给我。万分感谢。急需。。
hendrymc#vip.qq.com
2013-03-28 13:27
楼主,有没有完整的demo啊,我最近做windows phone动态调用webservice啊,一点不会啊。想求个demo
邮箱[email protected]
2012-06-24 13:33
微软极度变态而垃圾的为webs调用,以前同步调用的方法完全不能用了,本来很好用的,不知道吃错什么药了,非要异步调用
2012-06-28 01:18
异步挺好的,要习惯异步的思维
2011-07-20 19:49
楼主您好!我正在找windows phone 7实现异步获取webservice数据的方法,您那两个类文件链接失效了,能否将类文件或者示例代码发一份给我?kylin17#foxmail.com不胜感激!
2011-07-21 11:30
因为之前清理过一次Google Code SVN,我回家之后再传到svn上,届时会发link给你。