Ошибка службы маршрутизации WCF - несоответствие ContractFilter на EndPointDispatcher

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

  •  27-10-2019
  •  | 
  •  

Вопрос

Ситуация заключается в следующем: у меня есть внутренний сервер, управляющий некоторыми услугами WCF, и я хочу, чтобы они были доступны из Интернета в целом. С этой целью я написал сервис маршрутизации, которая работает на нашей публике, сталкиваясь с веб-сервер.

Эта служба маршрутизации, кажется, работает, однако, когда я пытаюсь вызвать метод, я всегда получаю следующую ошибку.

Сообщение с действием 'http://tempuri.org/iprocessmanagementservice/listprocesses' не может быть обработано в приемнике из -за несоответствия ContractFilter в EndpointDispatcher. Это может быть вызвано либо из -за несоответствия контракта (несоответствующие действия между отправителем и приемником), либо из -за несоответствия обязательства/безопасности между отправителем и получателем. Проверьте, что отправитель и получатель имеют тот же контракт и одинаковое обязательство (включая требования безопасности, например, сообщение, транспорт, нет).

Я попытался удалить все требования безопасности из Сервисов и использовал как конечные точки WSHTTP, так и бассейхттп. Похоже, ничего не делает. Однако служба маршрутизации правильно передает услуги MEX, поэтому Svcutil может создавать классы клиентов.

Я настраиваю маршрутизатор, хотя код. Службе маршрутизации предоставляется список имен услуг для обеспечения маршрутизации, а также адреса маршрутизатора и сервера.

Вот конфигурация для службы маршрутизации:

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

Он вызывает функцию со следующим кодом, предоставляя адрес маршрутизатора, адрес сервера и имена служб из файла конфигурации.

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;

Сервис вызывает эту функцию в начале, а затем открывает каждый из хостов службы, возвращенных в списке маршрутизаторов.

Сам сервер настроен через следующее app.config

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

Что мне не хватает?

РЕДАКТИРОВАТЬ: Я думаю, что нашел проблему- служба маршрутизации возвращала эту конфигурацию для Сервисов-

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

Это указывает на внутренний сервер, а не на внешний сервер. Понятия не имею, является ли это стандартным поведением для сервиса маршрутизации, или это переопределяемое поведение.

Это было полезно?

Решение

Похоже, что вы не подключались к клиентскому элементу ServiceModel в своей конфигурации должным образом. Routingservice должен быть настраивался, например, стандартную службу WCF, а также выявлять конечные точки «перехват» на маршрутируемые службы. Затем он использует конечные точки элемента клиента, чтобы перенаправить сервисные вызовы.

Ниже приведена простая конфигурация, которая не полагается на код. Он содержит соглашения об именах для различных значений маршрутизации, которые сохраняют все прямо. Вы можете заменить строку «yourroutedService» в конфигурации своим фактическим именем службы, но суффиксы должны оставаться, чтобы все подключилось правильно.

Я бы начал с того, что конфигурация на основе файлов успешно выполняет сквозные вызовы (никаких перекомпилировки не требуется при настройке с этим подходом). Затем основайте свой код на конфигурации файла и удалите настройки кода.

<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>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top