通过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);

问题好象解决了:)

 

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