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给你。