通過HttpWebRequest來請求webservice,Datatable無資料
webserivce似乎一下子變成遠古的東西了。轉到net6.0後,原引用服務的專案可以編譯,但執行時提示找不到“System.ServiceModel”云云。那就不引用,直接用HttpWebRequest傳送xml請求羅。
我們知道,asmx執行提示的內容已比較清晰的說明這個過程該如何呼叫。
好吧,其實早有人做好了。
https://www.cnblogs.com/weicanpeng/p/5755987.html
於是拿來使用,確實不錯。可是在使用DataTable入參的時候有問題,服務端得不到DataTable的資料。其實問題不是上圖的 xmlxml應是什麼格式呢?於是想到WireShark監控一下net40下的網路資料來獲取DataTable的XML格式。如果不知道如何用,推薦大家看一篇老文
但沒有經過網絡卡的請求不會被WireShark監控。怎麼辦?
我首先要解決的是,將webservice給其他電腦使用。我開發的筆記本是家庭版,沒有IIS,而我們除錯的專案跑起來似乎只會監控127.0.0.1,埠不會繫結到對外的IP上。想到了Nginx。好了,nginx轉到網絡卡的某個埠到127.0.0.1上我的webservice的埠。其他電腦終可以訪問。拿起放了幾年的小米筆記本(它的鍵盤很硬,是放了太久了嗎?),終於發現多臺電腦的好處了。得到抓包資料後,比較了兩者的XML差異,我幾乎要哭起來。
正常的XML有一個節點是這樣的
....><DocumentElement xmlns=""><....
不正常的XML對應的節點是這樣的
...><DocumentElement><...
在DataSet入參時也有類似情況,但節點是NewDataSet
正常的XML有一個節點是這樣的
...><NewDataSet xmlns=""><...
服務端DataSet的Table中沒有資料的XML是這樣的
...><NewDataSet><...
這個xmlns=""怎麼看都不可能是一個關鍵內容。相反一些xmlns不提供也沒有問題。真讓人無語。怎麼處理,直接文字replace。
修改了一個上面提到的文章中一個方法,https://www.cnblogs.com/weicanpeng/p/5755987.html
程式碼如下:
private static byte[] EncodeParsToSoap(Hashtable Pars, String XmlNs, String MethodName) { XmlDocument doc = new XmlDocument(); doc.LoadXml("<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"></s:Envelope>"); XmlElement soapBody = doc.CreateElement("s", "Body", "http://schemas.xmlsoap.org/soap/envelope/"); //soapBody.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");//缺失的xmlns,不加也行 //soapBody.SetAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");//缺失的xmlns,不加也行 XmlElement soapMethod = doc.CreateElement(MethodName); soapMethod.SetAttribute("xmlns", XmlNs); foreach (string k in Pars.Keys) { XmlElement soapPar = doc.CreateElement(k); soapPar.InnerXml = ObjectToSoapXml(Pars[k]); soapMethod.AppendChild(soapPar); } soapBody.AppendChild(soapMethod); doc.DocumentElement.AppendChild(soapBody); //return Encoding.UTF8.GetBytes(doc.OuterXml); string content = doc.OuterXml; content = content.Replace("<DocumentElement>", "<DocumentElement xmlns=\"\">");//解決DataTable入參沒有資料問題 content = content.Replace("<NewDataSet>", "<NewDataSet xmlns=\"\">");//解決DataSet入參沒有資料問題。 return Encoding.UTF8.GetBytes(content); }View Code
好了,我們寫一個代理類(繼承自DispatchProxy,在remoting時代用RealProxy),按著webservice寫一個interface,藉助代理類,WebServFactory寫一個CreateClient方法,以後就可以這樣來呼叫上面的asmx了。
IWebTest web = WebServFactory.CreateClient<IWebTest>("http://192.168.4.3:7492/TestService.asmx"); DataTable result = web.TransTable(table);
問題好象解決了:)