WSDL优先方法:如何为wsdl:port和wsdl:binding指定不同的名称?

Nir*_*jan 12 wcf wsdl

我遵循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文件相同的"wsdl:port/@ name".

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

请帮助我实现这一目标.

Lad*_*nka 18

您可以尝试实现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 };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

和配置:

  <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>
Run Code Online (Sandbox Code Playgroud)

我的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>
Run Code Online (Sandbox Code Playgroud)