通過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格式。如果不知道如何用,推薦大家看一篇老文https://www.cnblogs.com/A-yes/p/9894215.html

但沒有經過網卡的請求不會被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);

問題好象解決了:)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章