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

13

我正在遵循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生成服务器存根代码,并对生成的代码进行了轻微更改,以使WSDL与客户提供的完全相同,但我不知道在配置文件或生成的代码中进行什么更改才能获得与客户提供的wsdl文件中相同的“wsdl:port / @ name”。

根据这个网址,serviceendpoint名称属性映射到wsdl:port/@name和wsdl:binding/@name。基于此,在我的配置文件中,endpoint/@name属性值映射到wsdl:port/@name和wsdl:binding/@name,但我希望不同的名称映射到wsdl:port/@name和wsdl:binding/@name属性。
请帮我实现这个要求。
1个回答

19
你可以尝试实现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>

感谢您及时提供的帮助和代码。它解决了我的问题。 - Niranjan
通过接受一个答案,你可以向其他人快速传达你的问题已经解决。同时,你还会获得额外的 +2 声望值。 - ChrisF
抱歉回复晚了。我已经确认它已经被回答了。 - Niranjan
亲爱的Ladislav,请看一下我的问题,谢谢。 http://stackoverflow.com/questions/39635522/change-default-soap-schema-in-web-service-asmx-file - Imran Sh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接