调用非.net系统的Webservice的探索 ( 三 ) -WCF
?http://www.cnblogs.com/zitjubiz/archive/2011/09/27/WCF_Soap_Header.html 最近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 > 在园子里搜了一下,找到下面的方法? .net 调用 Java编写的WebService
但他这个文章,每个方法都要一个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); ?该方法调用成功,但它有个缺点,只适用了类比较少,没什么复杂类型的WebService,假如有上百个方法和自定义类,你还要自己解析xml包装成类,又等于重新造轮子,而且99%可能性没有微软造的好. ? 待续 To be continue... ? 调用非.net系统的Webservice的探索 ( 三 ) -WCF? WCF的模型和之前.net的WS有所不同. 你在添加Service Reference生成的代理类可以看到
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute( " System.ServiceModel ",? " 4.0.0.0 ")] public? partial? class?MathServiceClient?:?System.ServiceModel.ClientBase<IMathService>,?IMathService?{} ?而WCF著名的"ABC" ? 而我们这里调用java系统的WebService,只需要处理Address和Binding 来看看生成的app.config内容,留意黄色高亮的,是我们手工添加修改的.
<
configuration
>
???? < system.serviceModel > ???????? < bindings >???????????? ???????????? < customBinding > ???????????????? < binding? name ="IDrmServiceSoapHttp" > ???????????????????? < security? authenticationMode ="UserNameOverTransport" ? ??????????????????????????????allowInsecureTransport ="true" ?includeTimestamp ="false" > ???????????????????? </ security > ????????????????????? < textMessageEncoding? maxReadPoolSize ="64" ?maxWritePoolSize ="16" ????????????????????????messageVersion ="Soap11" ?writeEncoding ="utf-8" > ???????????????????????? < readerQuotas? maxDepth ="32" ?maxStringContentLength ="8192" ?maxArrayLength ="16384" ????????????????????????????maxBytesPerRead ="4096" ? maxNameTableCharCount ="65536" ? /> ???????????????????? </ textMessageEncoding > ???????????????????? < httpTransport? manualAddressing ="false" ?maxBufferPoolSize ="524288" ????????????????????????maxReceivedMessageSize ="65536" ?allowCookies ="false" ?authenticationScheme ="Anonymous" ????????????????????????bypassProxyOnLocal ="false" ?decompressionEnabled ="true" ?hostNameComparisonMode ="StrongWildcard" ????????????????????????keepAliveEnabled ="true" ?maxBufferSize ="65536" ?proxyAuthenticationScheme ="Anonymous" ????????????????????????realm ="" ?transferMode ="Buffered" ?unsafeConnectionNtlmAuthentication ="false" ????????????????????????useDefaultWebProxy ="true" ? /> ???????????????? </ binding > ???????????? </ customBinding > ???????????? ???????? </ bindings > ???????? < client > ???????????? ???????????? < endpoint? address ="http://localhost:8080/oracle-epm-drm-webservices/DrmService" ????????????????binding ="customBinding" ?bindingConfiguration ="IDrmServiceSoapHttp" ????????????????contract ="DRM.IDrmService" ?name ="DrmServicePortType" ? > ???????????????? < headers > ???????????????????? < AppParameters? xmlns ="http://drm.webservices.epm.oracle" > ???????????????????????? < serverUrl > http://DRMServer:5240/Oracle/Drm/APIAdapter </ serverUrl > ???????????????????????? < sessionParams > ProductVersion=11.1.2.1 </ sessionParams > ???????????????????? </ AppParameters > ???????????????? </ headers > ???????????? </ endpoint > ???????????? ???????? </ client > ???? </ system.serviceModel > </ configuration > ?调用方法如下:
MathServiceClient?svc?=?
new?MathServiceClient();
????????????svc.ClientCredentials.UserName.UserName?=? " MyUserName "; ????????????svc.ClientCredentials.UserName.Password?=? " MyPassword ";????????? label1.Text?=svc.Add( 1, 2);??????????????? WCF整个使用方法对比起WSE就简单很多了. 但作为客户端来说,我粗略测试了性能,和WSE差不多,WCF还略慢一点. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |