zoukankan      html  css  js  c++  java
  • 在基于WCF开发的Web Service导出WSDL定义问题及自定义wsdl:port 名称

             在契约优先的Web服务开发过程中,往往是先拿到WSDL服务定义,各家开发各自的服务实现或客户端,然后互相调用。

             尽管Web Service的标准已经发布很多年,但各个语言,框架对其实现仍然有差异,实际使用中仍有许多坑需要填。

            .NET平台下,ASP.NET Web Service的兼容性最好,对比较复杂一点的wsdl文件更较好的生成Proxy Stub代码,而WCF兼容性较差,遇到复杂一点的生产就会存在问题,而且从Java等平台的客户端调用也存在问题。但毕竟WCF很灵活,可以嵌入到任何应用中,不必必须是Web应用,这一点很诱人。

             在Web Service服务实现好以后,一般不会直接使用原来的wsdl定义文件,平台会根据导出契约自动生成wsdl,然后客户端会据此生成相应的Proxy访问代码。

    WCF导出WSDL的坑

          悲催的是,在我根据WSDL生成的类,并实现相应接口后,在导出的WSDL中找不到任何方法,基本就是空的,我还以为哪里的配置出来问题,百思不得其解。改来改去,最后,用攒机时的最小系统法来排除,原来问题出在OperationContract里的Action属性,这个属性是由WSDL文件生成代码时自动产生的,因此不敢去改,但正是因此,导致无法正确生成WSDL,删掉以后,一切正常。

    OperationContract的Action属性本是用于控制消息的派发,基本对应WSDL里定义的operation的名字,在一个服务里可以有一个方法Action=”*”来接收所有未处理的消息。

      [ServiceContract(Namespace="http://Microsoft.WCF.Documentation")]
      public interface ISampleService{
    
        [OperationContract(
          Action="http://Microsoft.WCF.Documentation/OperationContractMethod",
          Name="OCAMethod",
          ReplyAction="http://Microsoft.WCF.Documentation/ResponseToOCAMethod"
        )]
        string SampleMethod(string msg);
    
        [OperationContractAttribute(Action = "*")]
        void UnrecognizedMessageHandler(Message msg);
      }

    至于为何有他会影响我WSDL的导出,还希望高手指点。

    wsdl:port的名称的自定义

           本人先使用的使用Java平台的JAX-WS实现Linux下Web Service,然后在Windows上用客户端调用,客户端同时自己也实现Web Service,用于回调消息。这里问题就来了,同一个WSDL定义,在Java下面名称是XXXServerSoap,而在WCF里就是BasicHttpBinding_XXXServerSoap,这样在Java里回调的时候就失败了,本人Java不熟,不知道Java里为啥不能自动取可用的port,非得指定命名。这里最好能把BasicHttpBinding_这个前缀去掉,查了好久好像这是写死的,BasicHttpBinding这个名字可以改,但必须是BindingName_ServiceName这种形式。

        唯一有的办法就是写一个扩展,自定义WSDL导出过程,呵呵还真有人这么干

        public class PortNameWsdlBehavior : IWsdlExportExtension, IEndpointBehavior
        {
            public string Name { get; set; }
    
            public void ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)
            {
            }
    
            public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
            {
                if (!string.IsNullOrEmpty(Name))
                {
                    context.WsdlPort.Name = Name;
                }
            }
    
            public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
            {
            }
    
            public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
            {
            }
    
            public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
            {
            }
    
            public void Validate(ServiceEndpoint endpoint)
            {
            }
        }
    
        public class PortNameWsdlBehaviorExtension : BehaviorExtensionElement
        {
            [ConfigurationProperty("name")]
            public string Name
            {
                get
                {
                    Console.WriteLine("PortNameWsdlBehaviorExtension");
                    object value = this["name"];
                    return value != null ? value.ToString() : string.Empty;
                }
                set { this["name"] = value; }
            }
    
            public override Type BehaviorType
            {
                get { return typeof(PortNameWsdlBehavior); }
    Technorati 标签: ,,,,
            }
    
            protected override object CreateBehavior()
            {
                return new PortNameWsdlBehavior { Name = Name };
            }
        }
    拷贝,粘贴。在服务配置节<system.serviceModel>中加入扩展的配置:
      <extensions>
            <behaviorExtensions>
                <add name="portName" type="<NameSpace>.PortNameWsdlBehaviorExtension, <NameSpace>, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
            </behaviorExtensions>
     </extensions>
    搞定,这时候再看wsdl:port的name属性已经变成你的binding name了,你在配置文件里爱怎么配置怎么配置
  • 相关阅读:
    各种推荐资料汇总。。。
    不错的blog,做计算广告学的,还有机器学习的
    大数据建模,eBay的一个牛人
    factor graph和sum product和TrueSkill相关的两个blog,相当不错
    词云制作工具。。。
    CSS:nthchild选择器用法练习
    CSS控制表格隔行变色:nthchild()选择器
    CSS3calc()函数练习(制作响应式布局)
    CSS3boxsizing属性练习(borderbox设置padding和border不会改变width和height的值)
    CSS3clippath练习
  • 原文地址:https://www.cnblogs.com/jans2002/p/4673914.html
Copyright © 2011-2022 走看看