【问题标题】:WSDL-first approach: How to specify different names for wsdl:port and wsdl:binding?WSDL 优先方法:如何为 wsdl:port 和 wsdl:binding 指定不同的名称?
【发布时间】:2011-01-16 06:28:56
【问题描述】:

我正在遵循 WSDL 优先(由我们的客户提供)方法来开发 WCF 服务,但是从我的 wcf 服务生成的 WSDL 与我们的客户提供给我的 WSDL 略有不同,并且由于这种不匹配,客户面临着困难打电话给我的服务。

客户提供的wsdl:

<wsdl:service name='CheckoutService'> <wsdl:port binding='tns:CheckoutBinding' name='CheckoutServicePort'> <soap:address location='place holder to service uri' /> </wsdl:port> </wsdl:service>


从 wcf 服务生成的 WSDL:

<wsdl:service name="CheckoutService"> <wsdl:port binding="tns:CheckoutBinding" name="CheckoutBinging"> <soap:address location="place holder to service uri" /> </wsdl:port> </wsdl:service>

而且,我的服务设置如下:

<endpoint name="CheckoutBinding" address="" binding="basicHttpBinding" bindingName="CheckoutServicePort" bindingConfiguration="basicHttpBinding" bindingNamespace="<<namespace>>" contract="<<contractname>>" />

我已使用 WSCF.Blue 从客户端提供的 wsdl 生成服务器存根代码,并对生成的代码进行了细微更改以发出与客户端提供的完全相同的 WSDL,但我不知道要更改什么在配置文件或生成的代码中生成与客户端提供的 wsdl 文件中相同的“wsdl:port/@name”。

根据url,服务端点名称属性映射到 wsdl:port/@name 和 wsdl:binding/@name。基于此,我的配置文件中的 endpoint/@name 属性值映射到 wsdl:port/@name 和 wsdl:binding/@name 但我希望将不同的名称映射到 wsdl:port/@name 和 wsdl:binding/ @name 属性。

请帮助我实现这一目标。

【问题讨论】:

    标签: wcf wsdl


    【解决方案1】:

    您可以尝试实现 IWsdlExportExtension 并在 ExportEndpoint 中修改 wsdl:port/@name。然后实现 IEndpointBehavior,它将您的扩展添加到端点。要使用您的新行为,您有两个选择:

    • 从代码中添加行为。当服务托管在 IIS 中时,您必须创建自定义 ServiceHost 和 ServiceHostFactory。在自托管中,您只需迭代端点并添加行为。
    • 从配置中添加行为。您必须实现自定义 BehaviorExtensionElement,注册此元素并在与您的端点相关的端点行为中使用它。

    这是一个带有扩展元素的简单示例:

    using System;
    using System.Configuration;
    using System.ServiceModel.Configuration;
    using System.ServiceModel.Description;
    
    namespace CustomWsdlExtension    
    {
        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 
                { 
                    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="CustomWsdlExtension.PortNameWsdlBehaviorExtension, CustomWsdlExtension" />
          </behaviorExtensions>
        </extensions>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
          </serviceBehaviors>
          <endpointBehaviors>
            <behavior name="customPortName">
              <portName name="myCustomName" />
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <services>
          <service name="CustomWsdlExtension.Service">
            <endpoint address="" binding="basicHttpBinding" contract="CustomWsdlExtension.IService"
                      behaviorConfiguration="customPortName" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
    

    然后我的 WSDL 看起来像:

    <wsdl:service name="Service">
        <wsdl:port name="myCustomName" binding="tns:BasicHttpBinding_IService">
            <soap:address location="http://localhost:2366/Service.svc" /> 
        </wsdl:port>
    </wsdl:service>
    

    【讨论】:

    • 感谢您及时的帮助和代码。它解决了我的问题。
    • @user577260 - 通过接受答案,您可以快速直观地提示其他人您的问题已经解决。您还可以获得 +2 声望奖励。
    • 抱歉,回复晚了。我已经检查过了。
    • 亲爱的 Ladislav 请看我的问题,谢谢stackoverflow.com/questions/39635522/…
    猜你喜欢
    • 2013-09-18
    • 1970-01-01
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2019-06-11
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多