2009-09-25 14 views
8

Tengo un conjunto de contratos de servicio que dividen mi interfaz de servicio en fragmentos de funcionalidades relacionadas. Actualmente estoy implementando todos los contratos usando una sola clase de servicio (puede dividirlos más adelante, pero por ahora la clase de servicio individual es suficiente).Servicio alojado WCF IIS múltiples contratos de servicio implementados por un solo servicio: cómo comparto uri entre puntos finales a través de config

Estoy tratando de usar la configuración de los puntos finales utilizando un archivo de configuración (a diferencia del código de vía). El problema es que obtengo un ServiceActivationException porque los dos extremos (uno para cada contrato de servicio) están tratando de escuchar en el mismo uri. Los detalles de la excepción dicen que para lograr esto, los dos puntos finales deben compartir el objeto vinculante, lo cual tiene sentido, pero no puedo entender cómo hacerlo a través de config (no he intentado hacerlo a través del código ya que estoy alojado en IIS pero Puedo imaginarme que es un ejercicio simple de configurar en el código).

La siguiente es la configuración que uso actualmente (esto todavía está dev así que no estoy actualmente preocupados por los problemas de seguridad, etc., que algunos de estos ajustes pueden exponer a):

<system.serviceModel> 
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 
<services> 
    <service name="CDC.WebPortal.MidTier.MidTierAccessService" 
      behaviorConfiguration="MidTierServiceBehaviour" > 
    <endpoint address="" 
       binding="webHttpBinding" 
       bindingConfiguration="RestBindingConfiguration" 
       contract="****************************.IProductService" /> 

    <endpoint address="" 
       binding="webHttpBinding" 
       bindingConfiguration="RestBindingConfiguration" 
       contract="****************************.ICategoryService" /> 

    <endpoint address="mex" binding="mexHttpBinding" 
       contract="IMetadataExchange" /> 

    </service> 
</services> 

<bindings> 
    <webHttpBinding> 
    <binding name="RestBindingConfiguration" 
      maxReceivedMessageSize="104857600"> 
     <readerQuotas maxStringContentLength="104857600"/> 
    </binding> 
    </webHttpBinding> 
</bindings> 

<behaviors> 
    <serviceBehaviors> 
    <behavior name="MidTierServiceBehaviour"> 
     <serviceMetadata httpGetEnabled="true" /> 
     <serviceDebug includeExceptionDetailInFaults="false" /> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 

Entonces mi pregunta es ¿cómo comparto esta unión entre los dos puntos finales?

Los comentarios en this SO question sugieren que no puedo hacer esto, pero no creo que sea correcto.

ACTUALIZA 1this MS publication De acuerdo con lo que estoy haciendo debe estar bien ...

Update2 Aquí está el contenido del archivo SVC si ayuda:

<%@ ServiceHost Language="VB" Debug="true" 
       Service="*********************.MidTierAccessService" 
       Factory="Microsoft.ServiceModel.Web.WebServiceHost2Factory" %> 

ACTUALIZACIÓN 3 Aquí está el detalle de la excepción:

Un instalador vinculante ce ya se ha asociado para escuchar URI '********************'. Si dos puntos finales desean compartir el mismo ListenUri, también deben compartir la misma instancia de objeto vinculante . Los dos extremos conflictivos se especificaron en AddServiceEndpoint() llamadas, en un archivo de configuración, o una combinación de AddServiceEndpoint() y config.

ACTUALIZACIÓN 4 Ok echaba de menos this antes, indicando "Usted tendrá que utilizar direcciones relativas al exponer más de un punto final para un servicio particular, .svc". La causa de esto es algo relacionado con el directorio virtual de IIS que determina la dirección base del servicio. ¿Alguien puede explicar esto con un poco más de detalle, es decir, por qué IIS necesita un direccionamiento relativo para cada contrato?

Respuesta

7

Que yo sepa, y he estado trabajando mucho con WCF en el último mes, no puede compartir el mismo URI exacto para más de un punto final. En WCF, un "servicio" no está definido por la implementación de un contrato, sino por el contrato mismo (que también sigue las prácticas WSDL y SOA estándar). Los puntos finales le permiten exponer un solo servicio a través de múltiples protocolos (y por lo tanto diferentes direcciones) , pero no puede compartir diferentes servicios en la misma dirección exacta. Lógicamente eso no funcionaría.

Imagine la situación siguiente (que es lo que está tratando de lograr):

IProductService exposed @ http://localhost/service 
ICategoryService exposed @ http://localhost/service 
IMetadataExchange exposed @ http://localhost/service/mex 

Es bastante fácil para acceder al punto final MEX ... tiene un URI único. Sin embargo, ¿cómo se accede a IProductService o ICategoryService? No hay nada que le permita diferenciar los otros dos que no sean un URI. WCF no tiene nada que le permita enrutar entre los mensajes que se supone que van a IProductservice, y los que se supone que deben ir a ICategoryService. Dado que ambos usan el mismo URI, de hecho tienes un conflicto. Cada CONTRATO de servicio debe estar expuesto a través de un URI único. Todos los puntos finales que utilizan el mismo enlace exacto deben usar una dirección distinta.

Hay una manera de lograr lo que necesita. El problema es el enrutamiento de mensajes. WCF no admite de forma nativa el enrutamiento de mensajes OOB, sin embargo, sí proporciona la capacidad de implementar su propio enrutador de mensajes. (O, si está dispuesto a usar tecnología beta, .NET 4.0 viene con un enrutador de mensajes listo para usar, basado en los artículos vinculados a continuación, pero con una configuración mejorada). Michele Bustamante, una verdadera hechicera de WCF, ha proporcionado un implementación y artículo completo mensaje que describe el encaminamiento en los siguientes enlaces:

http://msdn.microsoft.com/en-us/magazine/cc500646.aspx http://msdn.microsoft.com/en-us/magazine/cc546553.aspx

La idea general es que se configura un único servicio que escucha en un único URI. Este servicio utiliza el envío de comodines a una sola operación de servicio, que luego determina a qué URI único encaminar cada mensaje. Puede hacer la determinación de la forma que desee, sin embargo, la más simple es a través de la Acción de solicitud, suponiendo que cada acción en sus dos interfaces, IProductService e ICategoryService, son únicas en el mundo. Sin embargo, terminará con más servicios ... el enrutador en sí es un servicio distinto de WCF que tendría que alojarse como cualquier otro.

+2

+1 para 'verdadera bruja' – dan

+0

@dan: lol: D Gracias. – jrista

Cuestiones relacionadas