wcf - WSDL 优先方法 : How to specify different names for wsdl:port and wsdl:binding?

标签 wcf wsdl

我正在遵循 WSDL-first(由我们的客户提供)方法来开发 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 生成服务器 stub 代码,并对生成的代码进行了细微的更改,以发出与客户端提供的 WSDL 完全相同的 WSDL,但我不知道要在配置文件或在生成的代码中获取与客户端提供的 wsdl 文件相同的“wsdl:port/@name”。

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

请帮助我实现这一目标。

最佳答案

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

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

  • 这是带有扩展元素的简单示例:
    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>
    

    关于wcf - WSDL 优先方法 : How to specify different names for wsdl:port and wsdl:binding?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4704148/

    相关文章:

    wcf - 读取WCF消息正文两次- "Message Cannot be read"

    wcf - 使用 TransportWithMessageCredential 时,受信任的人商店是否需要客户端证书

    c# - 从 WCF 架构验证器中抛出自定义响应

    visual-studio-2010 - 为什么VS会生成一个xs :nonNegativeInteger attribute for WCF client?的字符串属性

    php - Symfony2 使用 besimple/soap-client 包使用 SOAP 服务

    wcf - 如何处理/解析使用 WebClient 调用的 WCF Rest 的故障

    c# - 将 URI 参数映射到参数对象的属性?

    php - SoapClient LibXMLError : failed to load external entity, SOAP-ERROR:解析 WSDL:无法加载

    python - 使用转义的 xml 作为属性使用 SOAP web 服务

    python - 如何使用 suds (Python) 对 HTTP 代理进行身份验证?