2011-01-16 26 views
12

Estoy siguiendo el enfoque WSDL primero (proporcionado por nuestro cliente) para desarrollar el servicio WCF pero los WSDL generados a partir de mi servicio wcf son ligeramente diferentes de WSDL proporcionados por nuestro cliente y debido a este desajuste, el cliente enfrenta dificultades para hacer un llama a mi servicioPrimer acercamiento de WSDL: ¿Cómo especificar diferentes nombres para wsdl: port y wsdl: binding?

cliente proporcionado WSDL:

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


WSDL generado a partir de un servicio WCF:

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

y, mis ajustes de servicio son los siguientes:

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

he utilizado WSCF.Blue para la generación de código de servidor-talón del cliente WSDL y que fue puesto cambios menores en el código generado para emitir WSDL exactamente lo mismo que el proporcionado por el cliente, pero no estoy recibiendo alguna idea sobre qué cambio hacer en el archivo de configuración o en el código generado para obtener el mismo "wsdl: puerto/@ nombre" que en el archivo wsdl proporcionado por el cliente.

De acuerdo con esta url, la propiedad del nombre de la propiedad del servicio está asignada a wsdl: puerto/@ nombre y wsdl: enlace/@ nombre. En función de esto, el valor del atributo endpoint/@ name en mi archivo de configuración está asignado a wsdl: port/@ name y wsdl: binding/@ name, pero quiero asignar diferentes nombres a wsdl: port/@ name y wsdl: binding/@name atributos.

Amablemente ayúdenme a lograr esto.

Respuesta

17

Puede intentar implementar IWsdlExportExtension y en ExportEndpoint modificar wsdl: puerto/@ nombre. Luego implemente IEndpointBehavior que agregará su extensión a un punto final. Para usar su nuevo comportamiento, tiene dos opciones:

  • Agregue comportamiento desde el código. Cuando el servicio se aloja en IIS, debe crear ServiceHost y ServiceHostFactory personalizados. En autohosting puedes simplemente iterar puntos finales y agregar comportamiento.
  • Agregue comportamiento desde la configuración. Debe implementar BehaviorExtensionElement personalizado, registrar este elemento y usarlo en comportamientos de punto final relacionados con su punto final.

Aquí es simple ejemplo con el elemento de extensión:

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

y configuración:

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

Mi WSDL entonces se parece a:

<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

Gracias por su ayuda oportuna y código. Solucionó mi problema. – Niranjan

+0

@ user577260 - al aceptar una respuesta, le da una indicación visual rápida a otros de que su problema ha sido resuelto. También obtienes un bonificador de +2 rep. – ChrisF

+0

Disculpas, por responder tarde. Lo he comprobado como respondí. – Niranjan