WSDL-first approach: How to specify different names for wsdl:port and wsdl:binding?

后端 未结 1 1639
天涯浪人
天涯浪人 2020-12-01 13:17

I am following WSDL-first (provided by our client) approach for developing WCF service but WSDLs generated from my wcf service is slightly different from WSDL provided to me

相关标签:
1条回答
  • 2020-12-01 13:34

    You can try to implement IWsdlExportExtension and in ExportEndpoint modify wsdl:port/@name. Then implement IEndpointBehavior which will add your extension to an endpoint. To use your new behavior you have two choices:

    • Add behavior from code. When service is hosted in IIS you have to create custom ServiceHost and ServiceHostFactory. In self hosting you can just iterate endpoints and add behavior.
    • Add behavior from configuration. You must implement custom BehaviorExtensionElement, register this element and use it in endpointBehaviors related to your endpoint.

    Here is simple example with extension element:

    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 };
            }
        }
    }
    

    And configuration:

      <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>
    

    My WSDL then looks like:

    <wsdl:service name="Service">
        <wsdl:port name="myCustomName" binding="tns:BasicHttpBinding_IService">
            <soap:address location="http://localhost:2366/Service.svc" /> 
        </wsdl:port>
    </wsdl:service>
    
    0 讨论(0)
提交回复
热议问题