最近Oracle的DRM系统发布了新版本,其中的webService发生了重大的转变. 把验证信息放在了SoapHeader里面.
这样原来系统(在vs.net2005开发).net引用WebService就不能成功调用了. 因为默认的代理类调用是没有SoapHeader的.
新版DRM的Soap信息如下:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>UserName</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
<AppParameters xmlns="http://drm.webservices.epm.oracle">
<serverUrl>http://DRMServer:5240/Oracle/Drm/APIAdapter</serverUrl>
<sessionParams>ProductVersion=11.1.2.1</sessionParams>
</AppParameters>
</soap:Header>
<soap:Body xmlns:ns1="http://drm.webservices.epm.oracle">
<ns1:getVersions/>
</soap:Body>
</soap:Envelope>
<soap:Header>
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>UserName</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">Password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
<AppParameters xmlns="http://drm.webservices.epm.oracle">
<serverUrl>http://DRMServer:5240/Oracle/Drm/APIAdapter</serverUrl>
<sessionParams>ProductVersion=11.1.2.1</sessionParams>
</AppParameters>
</soap:Header>
<soap:Body xmlns:ns1="http://drm.webservices.epm.oracle">
<ns1:getVersions/>
</soap:Body>
</soap:Envelope>
但他这个文章,每个方法都要一个xml,太啰嗦了,我改成传MethodName和Param进去之后,重写整个<soap:body>
修改后的关键代码如下:
Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("WinFormDRMService.SoapHeader.xml");
xml = new XmlDocument();
xml.Load(stream);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
XmlNode SoaoBodyNode = xml.SelectSingleNode("soap:Envelope/soap:Body", nsmgr);
string SoapBodyNodeInnerXml = "<ns1:" + MethodName + ">";
//修改参数的值
foreach (DictionaryEntry de in Pars)
{
Hashtable subpars = de.Value as Hashtable;
//如果参数不是Hashtable,就直接用其key,value
if (subpars == null)
{
SoapBodyNodeInnerXml += "<ns1:" + de.Key.ToString() + ">";
SoapBodyNodeInnerXml += de.Value.ToString()+ "</ns1:" + de.Key.ToString() + ">";
}
else
{
SoapBodyNodeInnerXml += "<ns1:" + de.Key.ToString() + ">";
foreach (DictionaryEntry subde in subpars)
{
SoapBodyNodeInnerXml += "<ns1:" + subde.Key.ToString() + ">";
SoapBodyNodeInnerXml += subde.Value.ToString() + "</ns1:" + subde.Key.ToString() + ">";
}
SoapBodyNodeInnerXml += de.Value.ToString() + "</ns1:" + de.Key.ToString() + ">";
}
}
SoapBodyNodeInnerXml += "</ns1:" + MethodName + ">";
SoaoBodyNode.InnerXml = SoapBodyNodeInnerXml;
//将修改后的XML文件保存到流中
//这样做还可以保证发送的XML文件也是格式化的那种形式,而不是一整行
//如通过OuterXml获取的就是一整行,这样也可能会导致服务端解析失败,个人这次就碰到这种情况了
MemoryStream outStream = new MemoryStream();
xml.Save(outStream);
xml = new XmlDocument();
xml.Load(stream);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xml.NameTable);
nsmgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
XmlNode SoaoBodyNode = xml.SelectSingleNode("soap:Envelope/soap:Body", nsmgr);
string SoapBodyNodeInnerXml = "<ns1:" + MethodName + ">";
//修改参数的值
foreach (DictionaryEntry de in Pars)
{
Hashtable subpars = de.Value as Hashtable;
//如果参数不是Hashtable,就直接用其key,value
if (subpars == null)
{
SoapBodyNodeInnerXml += "<ns1:" + de.Key.ToString() + ">";
SoapBodyNodeInnerXml += de.Value.ToString()+ "</ns1:" + de.Key.ToString() + ">";
}
else
{
SoapBodyNodeInnerXml += "<ns1:" + de.Key.ToString() + ">";
foreach (DictionaryEntry subde in subpars)
{
SoapBodyNodeInnerXml += "<ns1:" + subde.Key.ToString() + ">";
SoapBodyNodeInnerXml += subde.Value.ToString() + "</ns1:" + subde.Key.ToString() + ">";
}
SoapBodyNodeInnerXml += de.Value.ToString() + "</ns1:" + de.Key.ToString() + ">";
}
}
SoapBodyNodeInnerXml += "</ns1:" + MethodName + ">";
SoaoBodyNode.InnerXml = SoapBodyNodeInnerXml;
//将修改后的XML文件保存到流中
//这样做还可以保证发送的XML文件也是格式化的那种形式,而不是一整行
//如通过OuterXml获取的就是一整行,这样也可能会导致服务端解析失败,个人这次就碰到这种情况了
MemoryStream outStream = new MemoryStream();
xml.Save(outStream);
该方法调用成功,但它有个缺点,只适用了类比较少,没什么复杂类型的WebService, 假如有上百个方法和自定义类, 你还要自己解析xml包装成类,又等于重新造轮子,而且99%可能性没有微软造的好.
待续 To be continue...
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
2004-09-23 如果aspx页面使用unicode,那么javascript也要使用unicode