DotNetCore用工具生成的代理类按下图设置用户密码访问webservice一直报用户密码验证不通过。
查了几天资料都无法突破。为此回到webservice的soap协议的本身来解决。soap的本质就是发布http服务接收按soap文档约定的xml串,然后按xml执行指定方法后返回xml个http调用客户端。然后就用httpclient来调用webservice就行了。
首先下载SOAPUI工具可以查看webservice请求的xml格式,还能测试调用,写代码前可以先用xml测试调用通了再写实现代码。
带用户密码验证的请求示例:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<wsa:Action>http://tempuri.org/LIS.WS.DHCLISService.GetData</wsa:Action>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>http://127.0.0.1:57772/imedicallis/csp/LIS.WS.DHCLISService.cls</wsa:To>
<wsse:Security soap:mustUnderstand="1">
<wsse:UsernameToken
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-29db7c92-1098-4717-b7fb-aac473632fec">
<wsse:Username>_SYSTEM1</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">SYS</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<GetData xmlns ="http://tempuri.org">
<ClassName>Service.LIS.QC.DHCQCService</ClassName>
<FuncName >GetMachineList</FuncName>
<Param >
</Param>
<Session ></Session>
</GetData >
</soap:Body>
</soap:Envelope>
也能把调用服务的请求端口和TCPTrace工具配置的监听端口一致然后用这个工具抓包看别的程序成功请求的提交XML串。基于这个串再到SOAPUI测试直到测通。
然后就实现DotNetCore的调用代理类即可
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Xml;
namespace LIS.DAL.DataAccess
{
///<summary NoteObject="Class">
/// [功能描述: 按soap协议自定义调用webservice客户端]<br></br>
/// [创建者: 张联珠]<br></br>
/// [创建时间: 2021-3-12]<br></br>
/// <说明>
///
/// </说明>
/// <修改记录>
/// <修改时间></修改时间>
/// <修改内容>
///
/// </修改内容>
/// </修改记录>
/// </summary>
public class MyWebserviceClient
{
/// <summary>
/// 服务地址
/// </summary>
private string Address = "";
/// <summary>
/// 用户名
/// </summary>
private string UserName = "";
/// <summary>
/// 用户密码
/// </summary>
private string UserPass = "";
/// <summary>
/// 构造函数
/// </summary>
/// <param name="address"></param>
/// <param name="userName"></param>
/// <param name="userPass"></param>
public MyWebserviceClient(string address, string userName, string userPass)
{
Address = address;
UserName = userName;
UserPass = userPass;
}
/// <summary>
/// 查询M得到数据
/// </summary>
/// <param name="ClassName">类名</param>
/// <param name="FuncName">方法名</param>
/// <param name="Param">参数</param>
/// <param name="Session">会话</param>
/// <returns></returns>
public string GetDataAsync(string ClassName, string FuncName, string Param, string Session)
{
string result = string.Empty;
try
{
string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
xml += "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">";
xml += "<soap:Header>";
xml += "<wsa:Action>http://tempuri.org/LIS.WS.DHCLISService.GetData</wsa:Action>";
xml += "<wsa:ReplyTo>";
xml += "<wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>";
xml += "</wsa:ReplyTo> ";
xml += "<wsa:To>" + Address + "</wsa:To>";
xml += "<wsse:Security soap:mustUnderstand=\"1\">";
xml += "<wsse:UsernameToken xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" wsu:Id=\"SecurityToken-29db7c92-1098-4717-b7fb-aac473632fec\">";
xml += "<wsse:Username>" + UserName + "</wsse:Username>";
xml += "<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">" + UserPass + "</wsse:Password>";
xml += "</wsse:UsernameToken>";
xml += "</wsse:Security>";
xml += "</soap:Header>";
xml += "<soap:Body>";
xml += "<GetData xmlns =\"http://tempuri.org\">";
xml += "<ClassName>" + ClassName + "</ClassName>";
xml += "<FuncName >" + FuncName + "</FuncName>";
xml += "<Param ><![CDATA[" + Param + "]]></Param>";
xml += "<Session >" + Session + "</Session>";
xml += "</GetData >";
xml += "</soap:Body>";
xml += "</soap:Envelope>";
HttpContent content = new StringContent(xml, Encoding.UTF8, "text/xml");
content.Headers.Add("SOAPAction", "http://tempuri.org/LIS.WS.DHCLISService.GetData");
using (HttpClient client = new HttpClient())
using (var response = client.PostAsync(Address, content))
{
result = response.Result.Content.ReadAsStringAsync().Result;
//创建一个xml文档
XmlDocument xmlDoc = new XmlDocument();
//为文档导入数据
xmlDoc.LoadXml(result);
result = xmlDoc.InnerText;
//调用报错了
if (!result.Contains("<Response>"))
{
result = "<Response><SQLResult><SQL><FunRet></FunRet></SQL></SQLResult><RetVal>-1</RetVal><Error>" + result + "</Error><Node></Node><RowCount>0</RowCount></Response>";
}
}
}
catch (Exception ex)
{
result = ex.Message;
}
return result;
}
/// <summary>
/// 查询M得到SQL执行结果
/// </summary>
/// <param name="SQLText">SQL串</param>
/// <param name="Param">参数</param>
/// <param name="Session">会话</param>
/// <returns>返回串</returns>
public string GetSQLDataAsync(string SQLText, string Param, string Session)
{
string result = string.Empty;
try
{
string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
xml += "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">";
xml += "<soap:Header>";
xml += "<wsa:Action>http://tempuri.org/LIS.WS.DHCLISService.GetSQLData</wsa:Action>";
xml += "<wsa:ReplyTo>";
xml += "<wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>";
xml += "</wsa:ReplyTo> ";
xml += "<wsa:To>" + Address + "</wsa:To>";
xml += "<wsse:Security soap:mustUnderstand=\"1\">";
xml += "<wsse:UsernameToken xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" wsu:Id=\"SecurityToken-29db7c92-1098-4717-b7fb-aac473632fec\">";
xml += "<wsse:Username>" + UserName + "</wsse:Username>";
xml += "<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">" + UserPass + "</wsse:Password>";
xml += "</wsse:UsernameToken>";
xml += "</wsse:Security>";
xml += "</soap:Header>";
xml += "<soap:Body>";
xml += "<GetSQLData xmlns = \"http://tempuri.org\">";
xml += "<SQLText>" + SQLText + "</SQLText>";
xml += "<Param>" + Param + "</Param >";
xml += "<Session>" + Session + "</Session>";
xml += "</GetSQLData>";
xml += "</soap:Body>";
xml += "</soap:Envelope>";
HttpContent content = new StringContent(xml, Encoding.UTF8, "text/xml");
content.Headers.Add("SOAPAction", "http://tempuri.org/LIS.WS.DHCLISService.GetSQLData");
using (HttpClient client = new HttpClient())
using (var response = client.PostAsync(Address, content))
{
result = response.Result.Content.ReadAsStringAsync().Result;
//创建一个xml文档
XmlDocument xmlDoc = new XmlDocument();
//为文档导入数据
xmlDoc.LoadXml(result);
result = xmlDoc.InnerText;
//调用报错了
if(!result.Contains("<Response>"))
{
result = "<Response><SQLResult><SQL><FunRet></FunRet></SQL></SQLResult><RetVal>-1</RetVal><Error>"+result+"</Error><Node></Node><RowCount>0</RowCount></Response>";
}
}
}
catch (Exception ex)
{
result = ex.Message;
}
return result;
}
}
}
这样就可以调通了额,适应所有webservice调用情况,要点就是回归soap协议,用httpclient发soapxml。结合抓包工具和soapui测试。