WCF -Routing -Service -Fehler - Vertragsfilter -Nichtübereinstimmung am EndpointDispatcher

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

  •  27-10-2019
  •  | 
  •  

Frage

Die Situation ist wie folgt: Ich habe einen internen Server mit einigen WCF -Diensten und möchte, dass sie aus dem Internet insgesamt zugänglich sind. Zu diesem Zweck habe ich einen Routing-Service geschrieben, der auf unserem öffentlichen Webserver ausgeführt wird.

Dieser Routing -Service scheint zu funktionieren, aber wenn ich versuche, eine Methode aufzurufen, erhalte ich immer den folgenden Fehler.

Die Nachricht mit Aktion 'http://tempuri.org/iprocessmanagementsservice/Listprocesses' kann aufgrund einer Vertragsfilter -Nichtübereinstimmung am EndpointDispatcher im Empfänger nicht verarbeitet werden. Dies kann entweder auf eine Vertragsfehlanpassung (nicht übereinstimmende Aktionen zwischen Absender und Empfänger) oder an einem Bindungs-/Sicherheitsmismatronen zwischen dem Absender und dem Empfänger liegen. Überprüfen Sie, ob Absender und Empfänger denselben Vertrag und die gleiche Bindung haben (einschließlich Sicherheitsanforderungen, z. B. Meldung, Transport, keine).

Ich habe versucht, alle Sicherheitsanforderungen aus den Diensten zu entfernen und sowohl WSHTTP- als auch BasisichTP -Endpunkte zu verwenden. Nichts scheint den Trick zu tun. Der Routing -Service gibt die MEX -Dienste jedoch ordnungsgemäß weiter, sodass SVCutil Kundenklassen erstellen kann.

Ich konfiguriere den Router durch Code. Der Routing -Dienst erhält eine Liste von Dienstnamen, um Routing für den Router und die Serveradressen bereitzustellen.

Hier ist die Konfiguration für den Routing -Dienst:

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

Es ruft eine Funktion mit dem folgenden Code auf und liefert die Router -Adresse, Serveradresse und Dienstnamen aus der Konfigurationsdatei.

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;

Der Dienst ruft diese Funktion zu Start auf und öffnet dann jeden der in der Router -Liste zurückgegebenen Diensthosts.

Der Server selbst ist über die folgende App.config konfiguriert

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

Was vermisse ich?

Bearbeiten: Ich denke, ich habe das Problem gefunden- der Routing-Dienst hat diese Konfiguration für die Dienste zurückgegeben.

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

Dies zeigt auf den internen Server, nicht auf den externen Server. Keine Ahnung, ob dies ein Standardverhalten für einen Routing -Dienst ist oder ob es sich um ein überschreibenes Verhalten handelt.

War es hilfreich?

Lösung

Es scheint, als hätten Sie das Servicemodel-Client-Element in Ihrer Konfiguration nicht richtig verkabelt. Der RoutingService muss wie ein Standard -WCF -Dienst konfiguriert und auch "Intercept" -Dendpunkte den Routed Services ausgesetzt werden. Anschließend werden die Client -Element -Endpunkte verwendet, um die Serviceanrufe umzuleiten.

Unten ist eine einfache Konfiguration, die nicht auf Code beruht. Es enthält Namenskonventionen für die verschiedenen Routing -Werte, die alles gerade halten. Sie können die Zeichenfolge "yourRoutedService" in der Konfiguration durch Ihren tatsächlichen Servicenamen ersetzen, aber die Suffixe sollten bleiben, um alles richtig zu verkabeln.

Ich würde damit beginnen, eine dateibasierte Konfiguration erfolgreich zu erhalten, die End-to-End-Anrufe erfolgreich tätigen (keine Neukompilien erforderlich, wenn Sie mit diesem Ansatz optimieren). Begräben Sie Ihren Code als Nächstes auf der Dateikonfiguration und entfernen Sie die konfigurierten Elemente.

<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>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top