调用非.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: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>
?調用方法如下:
????????????svc.ClientCredentials.UserName.UserName?=?"MyUserName";
????????????svc.ClientCredentials.UserName.Password?=?"MyPassword";?????????
label1.Text?=svc.Add(1,2);???????????????
WCF整個使用方法對比起WSE就簡單很多了.
但作為客戶端來說,我粗略測試了性能, 和WSE差不多,WCF還略慢一點.
?
總結
以上是生活随笔為你收集整理的调用非.net系统的Webservice的探索 ( 三 ) -WCF的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle的rank,over par
- 下一篇: [WCF]利用net.tcp傳輸協定來建