微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

调用非.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  @H_308_502@authenticationMode ="UserNameOverTransport"  
@H_308_502@                              allowInsecureTransport ="true" @H_308_502@ includeTimestamp ="false" >
                     </ security >
                      < textMessageEncoding  maxReadPoolSize ="64"  maxWritePoolSize ="16"
                        messageVersion
="Soap11"  writeEncoding ="utf-8" >
                         < readerQuotas  maxDepth ="32"  maxStringContentLength ="8192"  maxArrayLength ="16384"
                            maxBytesPerRead
="4096"   @H_308_502@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  @H_308_502@address ="http://localhost:8080/oracle-epm-drm-webservices/DrmService"
                binding
="customBinding"  bindingConfiguration ="IDrmServiceSoapHttp"
                contract
="DRM.IDrmService"  name ="DrmServicePortType"   >
                 < headers >
                     < AppParameters  @H_308_502@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( 12);               

WCF整个使用方法对比起WSE就简单很多了.

但作为客户端来说,我粗略测试了性能,和WSE差不多,WCF还略慢一点.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐