2010-03-02 11 views
6

Tengo un servicio WCF que tiene extremos REST y SOAP para cada servicio. Esto se implementó de manera similar a este mensaje: REST/SOAP endpoints for a WCF service con una configuración similar a la siguiente:Ocultar punto final REST de MEX/WSDL en WCF

<services> 
    <service name="TestService"> 
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
    <endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/> 
    <endpoint address="rest" binding="webHttpBinding" contract="ITestService"/> 
    </service> 
</services> 

El problema es que el punto final REST se muestra en el WSDL resultante como un puerto adicional y vinculante.

¿Hay alguna manera de evitar que se incluya el punto final REST en el WSDL?

Respuesta

1

Encontré decente forma de hacerlo con un IWsdlExportExtension. Probablemente haya una forma más robusta/reutilizable para hacer esto, pero esta solución requiere la convención de que todos los puntos finales REST se denominen "REST". A continuación se muestra la parte relevante de un comportamiento de punto final asociado a todos los puntos finales REST:

public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context) 
{ 
    // Remove all REST references (binding & port) from SOAP WSDL 
    foreach (ServiceDescription wsdl in exporter.GeneratedWsdlDocuments) 
    { 
     // Remove REST bindings 
     foreach (Binding binding in wsdl.Bindings) 
     { 
      if (binding.Name == "REST") 
      { 
       wsdl.Bindings.Remove(binding); 
       break; 
      } 
     } 

     // Remove REST ports 
     foreach (Service service in wsdl.Services) 
     { 
      foreach (Port port in service.Ports) 
      { 
       if (port.Name == "REST") 
       { 
        service.Ports.Remove(port); 
        break; 
       } 
      } 
     } 
    } 
} 
1

Puede obtener una copia del WSDL, editarlo manualmente para eliminar artefactos no deseados y almacenarlo en una ubicación conocida. Una vez que tenga la versión de su WSDL que elimina los artefactos no deseados, puede redirigir la consulta WSDL a ese lugar:?

<behaviors> 
<serviceBehaviors> 
    <behavior name="TestServiceBehavior"> 
    <serviceMetadata httpGetEnabled="True" externalMetadataLocation="http://localhost/TestService.wsdl"/> 
    </behavior> 
</serviceBehaviors> 
</behaviors> 

Un par de advertencias acerca de esta solución. Tienes que tener cuidado con lo que editas. Si cambia los aspectos críticos del contrato, es posible que WCF no pueda gestionar los mensajes de los clientes generados a partir de él. La eliminación de un punto final generalmente no es un gran problema, sin embargo cambiar los nombres de enlaces, operaciones, tipos de mensajes, etc. puede causar problemas.

También debe tener en cuenta las importaciones. El WSDL generado por WCF generalmente define los puntos finales, luego importa otro .wsdl que define el contrato de servicio real. El contrato de servicio wsdl in tern generalmente importa varios archivos .xsd que definen su mensaje y tipos de datos. Deberá asegurarse de tener copias de estas cargadas relativas a la raíz .wsdl, y de actualizar los elementos de importación para hacer referencia a ellas de manera adecuada.

Otro problema con esto es que ahora está controlando manualmente su contrato ... lo que significa que si lo cambia, debe editarlo nuevamente y reemplazarlo en el sitio donde esté alojando el archivo .wsdl. Ahora, un contrato diseñado adecuadamente NUNCA debe cambiar, ya que rompe una de las reglas fundamentales de SOA sobre los servicios web. Sin embargo, parece que está haciendo un desarrollo de código primero, por lo que es algo a tener en cuenta.

+0

La solución manual funcionará, sin embargo, como usted señala, está lejos de ser ideal. Para bien o para mal, este servicio evolucionará con el tiempo con nuevos métodos agregados periódicamente, por lo que el contrato cambiará. Estoy buscando una solución más automatizada, por lo que no tengo que acordarme de utilizar el WSDL en cada mejora del servicio. – WayneC

+1

No hay ninguna razón por la que no pueda automatizar el proceso. Es todo XML, y debería ser bastante fácil escribir algún proceso, tal vez incluso un script de Powershell, que se ejecuta como parte de su proceso de implementación. Podría desplegar todos los archivos de la consulta normal de wsdl, usar XPath para buscar y eliminar el elemento requerido e implementar todos los archivos .wsdl y .xsd. Finalmente, podría actualizar la configuración automáticamente para agregar el elemento a su comportamiento de enlace. – jrista

1

Sería bueno si hubiera un atributo para decorar el punto final de modo que esté oculto de la generación de mex/wsdl en versiones futuras de WCF por exactamente este motivo (ocultando servicios tranquilos de los clientes de soap).

Cuestiones relacionadas