Error de servicio de enrutamiento de WCF: desajuste de contrato en el EndpointDispatcher

StackOverflow https://stackoverflow.com/questions/6831111

  •  27-10-2019
  •  | 
  •  

Pregunta

La situación es la siguiente: tengo un servidor interno que ejecuta algunos servicios de WCF, y quiero que sean accesibles desde Internet en general. Con este fin, he escrito un servicio de enrutamiento que se ejecuta en nuestro servidor web de frente público.

Este servicio de enrutamiento parece funcionar, sin embargo, cuando intento invocar un método, siempre recibo el siguiente error.

El mensaje con Action 'http://tempuri.org/iprocessmanagementservice/listprocesss' no puede procesarse en el receptor, debido a una falta de coincidencia de contrato en el punto finalDISPatcher. Esto puede deberse a un desajuste de contrato (acciones no coincidentes entre el remitente y el receptor) o un desajuste vinculante/de seguridad entre el remitente y el receptor. Verifique que el remitente y el receptor tengan el mismo contrato y el mismo vinculante (incluidos los requisitos de seguridad, por ejemplo, mensaje, transporte, ninguno).

Intenté eliminar todos los requisitos de seguridad de los servicios y utilicé los puntos finales WSHTTP y BASICHTTP. Nada parece hacer el truco. Sin embargo, el servicio de enrutamiento está pasando correctamente los servicios MEX, por lo que SVCUTIL puede crear clases de clientes.

Estoy configurando el código enrutador. El servicio de enrutamiento recibe una lista de nombres de servicios para proporcionar enrutamiento y las direcciones del enrutador y el servidor.

Aquí está la configuración para el servicio de enrutamiento:

<MES.RoutingService.Properties.Settings>
   <setting name="RouterAddress" serializeAs="String">
    <value>http://localhost:8781/</value>
   </setting>
   <setting name="ServerAddress" serializeAs="String">
    <value>http://10.4.1.117:8781/</value>
   </setting>
   <setting name="Services" serializeAs="Xml">
    <value>
     <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <string>ProcessManagementService</string>
      <string>TestProcessService</string>
      <string>ProcessDataEntryService</string>
      <string>ProcessReportingService</string>
     </ArrayOfString>
    </value>
   </setting>
  </MES.RoutingService.Properties.Settings>

Llama a una función con el siguiente código, proporcionando la dirección del enrutador, la dirección del servidor y los nombres de servicio del archivo de configuración.

var routers = new List<ServiceHost>();
        foreach (var service in _services)
        {
            var routerType = typeof(IRequestReplyRouter);
            var routerContract = ContractDescription.GetContract(routerType);
            var serviceHost = new ServiceHost(typeof (System.ServiceModel.Routing.RoutingService));             
            var serverEndpoints = new List<ServiceEndpoint>();              

            //Configure Mex endpoints
            serviceHost.AddServiceEndpoint(routerType, MetadataExchangeBindings.CreateMexHttpBinding(), _routerAddress + service + "/mex");
            serverEndpoints.Add(new ServiceEndpoint(routerContract, MetadataExchangeBindings.CreateMexHttpBinding(), new EndpointAddress(_serverAddress + service + "/mex")));

            //RAR SECURITY SMASH.
            var binding = new WSHttpBinding(SecurityMode.None);
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
            binding.Security.Message.EstablishSecurityContext = false;
            binding.Security.Message.NegotiateServiceCredential = false;
            binding.Security.Message.ClientCredentialType = MessageCredentialType.None;

            //Configure WsHttp endpoints
            serviceHost.AddServiceEndpoint(routerType, binding, _routerAddress + service);              
            serverEndpoints.Add(new ServiceEndpoint(routerContract, binding, new EndpointAddress(_serverAddress + service)));

            var basicBinding = new BasicHttpBinding();
            serviceHost.AddServiceEndpoint(routerType, basicBinding, _routerAddress + service + "/basic");
            serverEndpoints.Add(new ServiceEndpoint(routerContract, basicBinding, new EndpointAddress(_serverAddress + service + "/basic")));

            //Set Routing Tables
            var configuration = new RoutingConfiguration();
            configuration.FilterTable.Add(new MatchAllMessageFilter(), serverEndpoints);
            serviceHost.Description.Behaviors.Add(new RoutingBehavior(configuration));

            routers.Add(serviceHost);
        }
        return routers;

El servicio llama a esta función al inicio y luego abre cada uno de los hosts de servicio devueltos en la lista de enrutadores.

El servidor en sí está configurado a través de la siguiente aplicación.

<system.serviceModel>
  <bindings>
   <wsHttpBinding>
    <binding name="noSecurityBinding">
     <security mode="None">
      <transport clientCredentialType="None" />
      <message establishSecurityContext="false" />
     </security>
    </binding>
   </wsHttpBinding>   
  </bindings>
  <services>
   <service name="MES.ProcessManagerServiceLibrary.ProcessManagementService">
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <endpoint binding="wsHttpBinding" bindingConfiguration="noSecurityBinding"
     contract="MES.ProcessManagerServiceLibrary.IProcessManagementService" />
    <endpoint address="basic" binding="basicHttpBinding" bindingConfiguration=""
     contract="MES.ProcessManagerServiceLibrary.IProcessManagementService" />
    <host>
     <baseAddresses>
      <add baseAddress="http://localhost:8781/ProcessManagementService/" />
     </baseAddresses>
    </host>
   </service>
   <service name="MES.ProcessManagerServiceLibrary.TestProcessService">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="noSecurityBinding"
     contract="MES.ProcessManagerServiceLibrary.ITestProcessService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <endpoint address="basic" binding="basicHttpBinding" bindingConfiguration=""
     contract="MES.ProcessManagerServiceLibrary.ITestProcessService" />    
    <host>
     <baseAddresses>
      <add baseAddress="http://localhost:8781/TestProcessService/" />
     </baseAddresses>
    </host>
   </service>
   <service name="MES.ProcessManagerServiceLibrary.ProcessDataEntryService">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="noSecurityBinding"
     contract="MES.ProcessManagerServiceLibrary.IProcessDataEntryService" />
    <endpoint address="basic" binding="basicHttpBinding" bindingConfiguration=""
    contract="MES.ProcessManagerServiceLibrary.IProcessDataEntryService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
     <baseAddresses>
      <add baseAddress="http://localhost:8781/ProcessDataEntryService/" />
     </baseAddresses>
    </host>
   </service>
   <service name="MES.ProcessManagerServiceLibrary.ProcessReportingService">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="noSecurityBinding"
     contract="MES.ProcessManagerServiceLibrary.IProcessReportingService" />
    <endpoint address="basic" binding="basicHttpBinding" bindingConfiguration=""
    contract="MES.ProcessManagerServiceLibrary.IProcessReportingService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
     <baseAddresses>
      <add baseAddress="http://localhost:8781/ProcessReportingService/" />
     </baseAddresses>
    </host>
   </service>
  </services>
  <behaviors>
   <serviceBehaviors>
    <behavior>
     <!-- To avoid disclosing metadata information, 
     set the value below to false and remove the metadata endpoint above before deployment -->
     <serviceMetadata httpGetEnabled="True"/>
     <!-- To receive exception details in faults for debugging purposes, 
     set the value below to true. Set to false before deployment 
     to avoid disclosing exception information -->
     <serviceDebug includeExceptionDetailInFaults="True"/>
    </behavior>
   </serviceBehaviors>
  </behaviors>
 </system.serviceModel>

¿Qué me estoy perdiendo?

Editar: creo que encontré el problema: el servicio de enrutamiento estaba devolviendo esta configuración para los servicios-

<client>
   <endpoint address="http://shco-appsrv1.us.shepherd.ad:8781/ProcessManagementService/"
    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IProcessManagementService"
    contract="IProcessManagementService" name="WSHttpBinding_IProcessManagementService" />
   <endpoint address="http://shco-appsrv1.us.shepherd.ad:8781/ProcessManagementService/basic"
    binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IProcessManagementService"
    contract="IProcessManagementService" name="BasicHttpBinding_IProcessManagementService" />
 </client>

Esto apunta al servidor interno, no al servidor externo. No tengo idea de si este es un comportamiento estándar para un servicio de enrutamiento, o si es un comportamiento innumerable.

¿Fue útil?

Solución

Parece que no ha conectado el elemento del cliente ServiceModel en su configuración correctamente. El RutingService debe configurarse como un servicio WCF estándar y también exponer puntos finales de "intercepción" a los servicios enrutados. Luego usa los puntos finales del elemento del cliente para redirigir las llamadas de servicio.

A continuación se muestra una configuración simple que no depende del código. Contiene convenciones de nombres para los diversos valores de enrutamiento que mantienen todo recto. Puede reemplazar la cadena "YourRoutedService" en la configuración con el nombre de su servicio real, pero los sufijos deben permanecer para mantener todo conectado correctamente.

Comenzaría a obtener una configuración basada en archivos con éxito que realice llamadas de extremo a extremo (no se necesitan recompilas al ajustar con este enfoque). A continuación, base su código en la configuración del archivo y elimine los elementos que se están configurando.

<system.serviceModel>
    <services
        name="System.ServiceModel.Routing.RoutingService"
        behaviorConfiguration="RoutingBehavior" >
        <endpoint
            name="RouterEndpoint"
            address=""
            binding="wsHttpBinding"
            bindingConfiguration="Http"
            contract="System.ServiceModel.Routing.IRequestReplyRouter" />

        <!-- List all endpoints to be routed via EndpointName routing filter -->
        <endpoint
            name="YourRoutedServiceName"
            address="YourRoutedService"
            contract="System.ServiceModel.Routing.IRequestReplyRouter"
            binding="wsHttpBinding"
            bindingConfiguration="Http" />
    </services>
    <routing>
        <filters>
            <!-- Active filters -->
            <filter
                name="YourRoutedServiceFilter"
                filterType="EndpointName"
                filterData="YourRoutedServiceName" />
        </filters>
        <filterTables>
            <filterTable name="WebLayer">
                <!-- Map to client Endpoints-->
                <add
                    filterName="YourRoutedServiceFilter"
                    endpointName="YourRoutedServiceNameEndpoint"
                    priority="0" />
            </filterTable>
        </filterTables>
    </routing>
    <behavior name="RoutingBehavior">
        <routing routeOnHeadersOnly="false" filterTableName="WebLayer" />
        <serviceDebug includeExceptionDetailInFaults="true" />
        <serviceMetadata httpsGetEnabled="true"  />
    </behavior>
    <bindings>
        <wsHttpBinding>
            <binding name="Http">
                <security mode="None" />
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint
            name="YourRoutedServiceNameEndpoint"
            address="http://somehost/YourRoutedService/Service.svc"
            contract="*"
            binding="wsHttpBinding"
            bindingConfiguration="Http" />
    </client>
</system.serviceModel>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top