惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
V
Vulnerabilities – Threatpost
G
GRAHAM CLULEY
Simon Willison's Weblog
Simon Willison's Weblog
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Privacy International News Feed
H
Heimdal Security Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Secure Thoughts
MyScale Blog
MyScale Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
V
Visual Studio Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
L
LINUX DO - 最新话题
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Cloudflare Blog
美团技术团队
Recorded Future
Recorded Future
T
Tailwind CSS Blog
Latest news
Latest news
Security Archives - TechRepublic
Security Archives - TechRepublic
Security Latest
Security Latest
Know Your Adversary
Know Your Adversary
Cloudbric
Cloudbric
Schneier on Security
Schneier on Security
I
Intezer
L
LINUX DO - 热门话题
P
Palo Alto Networks Blog
云风的 BLOG
云风的 BLOG
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Vercel News
Vercel News
Attack and Defense Labs
Attack and Defense Labs
人人都是产品经理
人人都是产品经理
L
LangChain Blog
爱范儿
爱范儿
博客园 - 三生石上(FineUI控件)
博客园 - 叶小钗
L
Lohrmann on Cybersecurity
S
SegmentFault 最新的问题
W
WeLiveSecurity
C
Cybersecurity and Infrastructure Security Agency CISA
S
Securelist
SecWiki News
SecWiki News
V2EX - 技术
V2EX - 技术
IT之家
IT之家
Cyberwarzone
Cyberwarzone
F
Full Disclosure
Spread Privacy
Spread Privacy
阮一峰的网络日志
阮一峰的网络日志

博客园 - Jans

Flutter运行时闪退 利用 Python 爬虫来对文本进行批量化翻译 Thinkpad T460声音问题 Error 56: The Cisco Systems, Inc. VPN Service has not been started(Cisco VPN在Vista/Win 7下出现Error 56的解决办法) - Jans Weblogic中配置Active Directory Authentication Provider weblogic 10.3.5重置密码 JNI:在线程或信号处理函数中访问自定义类 (转)Java实现Web Service过程中处理SOAP Header的问题 Geek to Live: Set up your personal Wikipedia (转)GitHub上整理的一些工具,求补充 - (转)老衣的开发工具和类库集之2014版 GCC的内存边界对齐 如何删除Weblogic域 电蚊拍选购参考 Localizing WPF with .resx files C#操作串口总结 ASP.NET MVC的国际化问题 小众的分布式版本管理工具Code Co-op 关于效率长尾现象
在基于WCF开发的Web Service导出WSDL定义问题及自定义wsdl:port 名称
Jans · 2015-07-24 · via 博客园 - Jans

         在契约优先的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); }
        }

        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了,你在配置文件里爱怎么配置怎么配置