调用非.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( 12);               

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

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值