Несоответствие ContractFilter в исключении EndpointDispatcher


116

У меня есть следующий сценарий, который я пытаюсь проверить:

  1. Общий WSDL
  2. Конечная точка WCF, которая реализует объекты на основе WSDL и размещается в IIS.
  3. Клиентское приложение, использующее прокси на основе WSDL для создания запросов.

Когда я вызываю веб-службу от клиента к конечной точке службы, я получаю следующее исключение:

{"Сообщение с действием ' http: // IMyService / CreateContainer ' не может быть обработано в получателе из-за несоответствия ContractFilter в EndpointDispatcher. Это может быть из-за несоответствия контракта (несоответствия действий отправителя и получателя) или Несоответствие привязки / безопасности между отправителем и получателем. Убедитесь, что отправитель и получатель имеют одинаковый контракт и одинаковую привязку (включая требования безопасности, например сообщение, транспорт, нет). "}

Я начал использовать MS Service Trace Viewer, но не знал, где искать. При просмотре классов в клиенте и конечной точке они кажутся идентичными.

Как начать устранять эту проблему?

Каковы возможные причины этого исключения?

Ответы:


75

«Несоответствие ContractFilter в EndpointDispatcher» означает, что получатель не смог обработать сообщение, поскольку оно не соответствует ни одному из контрактов, настроенных получателем для конечной точки, получившей сообщение.

Это может быть потому, что:

  • У вас разные контракты между клиентом и отправителем.
  • Вы используете другую привязку между клиентом и отправителем.
  • Параметры безопасности сообщений не согласованы между клиентом и отправителем.

Взгляните на EndpointDispatcherкласс для получения дополнительной информации по этому вопросу.

Так:

Убедитесь, что ваши клиентские и серверные контракты совпадают.

  • Если вы создали свой клиент из WSDL, актуален ли WSDL?
  • Если вы недавно внесли изменения в контракт, развернули ли вы правильную версию клиента и сервера?
  • Если вы вручную создали классы клиентского контракта, убедитесь, что пространства имен, имена элементов и имена действий соответствуют тем, которые ожидает сервер.

Убедитесь, что привязки между клиентом и сервером одинаковы.

  • Если вы используете файл .config для управления конечными точками, убедитесь, что элементы привязки совпадают.

Убедитесь, что настройки безопасности одинаковы для клиента и сервера.

  • Если вы используете файл .config для управления конечными точками, убедитесь, что элементы безопасности совпадают.

3
также убедитесь, что атрибут службы указан правильно в файле .svc. Смотрите мой ответ ниже.
AntonK

Просто хотел добавить к решению выше (для новичков), так как я столкнулся с той же проблемой, но указанное выше решение не сработало для меня. Если вы уже пробовали описанные выше обходные пути и по-прежнему получаете ту же ошибку, попробуйте обновить конфигурацию, просто перепечатав задействованные конечные точки, даже если они уже верны как на сервере, так и на клиенте.
devpro101 01

75

У меня была эта ошибка, и она была вызвана тем, что контракт Recevier не реализует вызываемый метод. По сути, кто-то не развернул последнюю версию службы WCF на хост-сервере.


13
+1 - То же самое произошло и со мной, только в моем случае это я был «кем-то». Я забыл зафиксировать и развернуть серверный код.
Джесси Уэбб

2
Ага, я неправильно назвал действие SOAP. Он хотел tempuri.org/ICodeGenService/RenderApp , но по какой-то причине код, анализирующий WSDL, думал, что это просто tempuri.org/RenderApp .
user435779

Я тоже. У меня был метод в моем .SVC.CS, но не было соответствующего OperationContract в моем интерфейсе.
PahJoker

Я тоже :) Я обновил WSDL в SoapUI, используя локальную службу, находящуюся в разработке, и когда я создал запрос на новый метод в службе, SoapUI использовал нашу среду разработки. Итак, метод работал нормально, я просто запросил неправильный URL.
Larsbj

2
Спасибо! Я не тратил часы на отладку, вместо этого, прочитав это, я быстро понял, что отправляю запросы в неправильную среду.
Ян Матушек

20

Вы также получите это, если попытаетесь подключиться к неправильному URL-адресу ;)

В моей системе определены две конечные точки и службы с похожими именами.

Получил эту точную ошибку, когда в какой-то момент на моем клиенте менялись URL-адреса. Действительно почесал затылок, пока наконец не выяснил эту глупую ошибку.


3
Совершенно глупая ошибка, но здесь очень полезный ответ. Поскольку это что-то очевидное, это легко не заметить.
mungflesh


20

У меня возникла эта проблема, и я обнаружил, что в своем генераторе прокси, который я скопировал из другой службы, я забыл изменить имя службы.

Я изменил это ...

Return New Service1DataClient(binding, New EndpointAddress(My.Settings.WCFServiceURL & "/Service1Data.svc"))

чтобы ...

Return New Service2DataClient(binding, New EndpointAddress(My.Settings.WCFServiceURL & "/Service2Data.svc"))

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


Так было и со мной.
Василий Боровяк

Спасибо, у меня была такая же проблема!
Dieterg

10

Для клиента Java, вызывающего конечную точку .net. Это было вызвано несоответствием заголовка Soap Action.

Content-Type: application/soap+xml;charset=UTF-8;action="http://example.org/ExampleWS/exampleMethod"

Приведенный выше HTTP-заголовок или следующий за ним XML-тег должен соответствовать действию / методу, которое вы пытаетесь вызвать.

   <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/" xmlns:gen="http://schemas.datacontract.org/2004/07/GenesysOnline.WCFServices">
   <soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsa:To>https://example.org/v1/Service.svc</wsa:To>
      <wsa:Action>http://example.org/ExampleWS/exampleMethod</wsa:Action>
   </soap:Header>
   <soap:Body>
    ...
   </soap:Body>
</soap:Envelope>

9

Я решил это, добавив в свою реализацию контракта следующее:

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]

Например:

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
public class MyUploadService : IMyUploadService
{

}

Это решило мою проблему с перенаправленным портом. Спасибо.
Матиас Мюллер,

Нет, у меня новая ошибка, я ненавижу IIS - CommunicationException: сервер не предоставил значимый ответ; это может быть вызвано несоответствием контракта, преждевременным завершением сеанса или внутренней ошибкой сервера.
AriesConnolly,

8

Я получил это после того, как скопировал файл svc и переименовал его. Хотя имя файла и файл svc.cs были правильно переименованы, разметка по-прежнему ссылалась на исходный файл.

Чтобы исправить это, щелкните правой кнопкой мыши скопированный файл svc, выберите « Просмотр разметки» и измените ссылку на службу.


5

Как упоминалось в других ответах, таких как @chinto, это происходит, когда элемент заголовка SOAP: Action не соответствует конечной точке.

Вы можете найти правильный URI, просмотрев WSDL сервера. Вы увидите элемент операции с дочерним элементом input, имеющим атрибут «Action». Это то, что нужно вашему SOAP: Action по запросу клиента.

<wsdl:operation name="MethodName">
<wsdl:input wsaw:Action="http://tempuri.org/IInterface/MethodName" message="tns:IInterface_MethodName_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IInterface/MethodNameResponse" message="tns:IInterface_MethodName_OutputMessage"/>
</wsdl:operation>

после нескольких дней поиска в Google, тестирования и безумия - этот ответ мне помог. Спасибо.
babboon

в моем конкретном сценарии я делал вызов WebService из моего класса java, используя Apache HttpClient. Чтобы установить заголовок действия Soap, я вызвал метод HttpPost SetHeader сразу после того, как вызвал метод setHeader для setContent Type.
вофили

3

Я была такая же проблема. Проблема заключалась в том, что я скопировал код из другой службы в качестве отправной точки и не изменил класс службы в файле .svc.

Откройте файл .svc и убедитесь, что атрибут Service указан правильно.

 <%@ ServiceHost Language="C#" Debug="true" Service="SME.WCF.ApplicationServices.ReportRenderer" CodeBehind="ReportRenderer.svc.cs" %>

2

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

Например, клиент использует nettcpip, а сервер настроен на использование базового http.


2

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


1

Эта ошибка обычно возникает, если код развернут неправильно.

В моем случае у меня есть две службы ServiceA и ServiceB. Я обнаружил проблему в том, что файлы ServiceB не были развернуты должным образом. Из-за чего, когда ServiceA вызывал ServiceB изнутри, он выдавал ошибку ниже.

**Ошибка**

Убедитесь, что файлы и ссылки правильно развернуты.


1

Я целыми днями искал ответ и нашел его, но не в этой теме. Я новичок в WCF и C #, поэтому для некоторых ответ может быть очевиден.

В моей ситуации у меня был клиентский инструмент, который изначально был разработан для службы ASMX, и для меня он возвращал то же сообщение об ошибке.

Попробовав всевозможные рекомендации, я нашел этот сайт:

http://myshittycode.com/2013/10/01/the-message-with-action-cannot-be-processed-at-the-receiver-due-to-a-contractfilter-mismatch-at-the-endpointdispatcher/

Это поставило меня на правильный путь. В частности, «мыло: операция» - WCF добавлял ServiceName к пространству имен:

клиент ожидал Http://TEST.COM/Login, но WCF отправил Http://TEST.COM/IService1/Login. Решение состоит в том, чтобы добавить [OperationContract]такую настройку :

[OperationContract(Action = "http://TEST.COM/Login", ReplyAction = "http://TEST.COM/Login")] (Игнорировать пробелы в Http)


2
Хорошо. Ваше решение - заставить службу вести себя так, как ожидает какой-то клиент. Но с тем же успехом (или, во многих случаях, предпочтительно) эту проблему можно решить, если клиент действительно будет выполнять контракт с сервером! В конце концов, сервер является издателем контракта.
The Dag

1

Это могло быть по двум причинам:

  1. Ссылка на службу устарела, щелкните правой кнопкой мыши ссылку службы и обновите ее.

  2. заключенный вами контракт может отличаться от того, что есть у клиента. Сравните обе службы и клиентский контракт и устраните несоответствие контрактов.


1

Если вы вызываете метод WCF, вы должны включить интерфейс в заголовок.

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(Url);
if (Url.Contains(".svc"))
{
    isWCFService = true;
    req.Headers.Add("SOAPAction", "http://tempuri.org/WCF_INterface/GetAPIKeys");
}
else 
{
    req.Headers.Add("SOAPAction", "\"http://tempuri.org/" + asmxMethodName+ "\"");
}

1

Также это может быть полезно для тех, кто занимается кодированием. Вам необходимо добавить WebHttpBehavior () в добавленную конечную точку службы. Что-то вроде:

restHost.AddServiceEndpoint(typeof(IRestInterface), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior()); 

Взгляните на: https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/calling-a-rest-style-service-from-a-wcf-service


Это помогло мне сэкономить время, спасибо :)
Сели Личи

0

Глупо, но я забыл добавить [OperationContract]в свой служебный интерфейс (тот, что отмечен [ServiceContract]), и тогда вы также получите эту ошибку.


0

Ваш клиент не был обновлен. Обновите свои службы из веб-службы, а затем перестройте проект.


0

У меня тоже была эта проблема. Оказалось, что это было вызвано сериализатором контрактов на стороне сервера. Он не мог вернуть мой объект контракта данных, потому что некоторые из его данных были свойствами только для чтения .

Убедитесь, что у ваших объектов есть сеттеры для свойств, которые должны быть сериализованы.


0

Как ни странно, мы обошли эту ошибку, используя тот же регистр, что и для имени Path и OperationContract. Видимо это было с учетом регистра. Если кто знает почему, прокомментируйте. Спасибо!


0

Итак, мой случай был следующим. Я не использовал прокси для взаимодействия клиент-сервер, я использовал ChannelFactory (поэтому все советы по обновлению до ссылки на сервис были для меня бессмысленными).

Служба размещалась в IIS, и по какой-то причине в папке bin были неправильные ссылки. Перекомпиляция проекта просто не привела к появлению новых dll в этой папке.

Поэтому я просто удалил все оттуда и добавил ссылку на службу в том же решении, затем перекомпилировал, и теперь все работает.


0

Моя проблема оказалась чем-то редким, но я все равно упомяну об этом.

Я столкнулся с проблемой развертывания в нашей среде разработки. На этой машине наш специалист по сборке создал две папки (развернул два приложения). Старая версия и новая текущая версия. Поэтому, если у вас нет двух версий вашего приложения на веб-сервере, это к вам не относится.

Новое местоположение, которое он создал, имело нестандартное имя в качестве первой части URL-адреса после хоста:

net.tcp://dev.umbrellacorp.com/DifferentFolderName/MyProvider

На моем локальном компьютере мой клиент указывал на стандартное имя папки, которое было настроено во всех средах (кроме разработки), включая мою локальную среду.

net.tcp://dev.umbrellacorp.com/AppServices/MyProvider

Когда я сдул и заменил web.config при разработке своей локальной копией, часть URL-адреса, которая должна была быть особенной, была заменена стандартной частью, поэтому в результате клиент на dev указал на старое приложение.

У старого приложения был старый контракт, и оно не понимало запрос и выдавало эту ошибку.


0

У меня была такая же ошибка в развернутой службе WCF, проблема была связана с другой службой, развернутой с другим контрактом с тем же портом.

Решение

Я использовал разные порты в web.config, и проблема исчезла.

Сервис 1

contract="Service.WCF.Contracts.IBusiness1" 
baseAddress="net.tcp://local:5244/ServiceBusiness" 

Сервис 2

contract="Service.WCF.Contracts.IBusiness2"
baseAddress="net.tcp://local:5243/ServiceBusiness"

Кроме того , я столкнулся с этой ситуацией, используя другой порт для одного и того же адреса между службой и потребителем.


0

У меня была эта ошибка, потому что у меня есть старая версия DLL в GAC моего сервера. Поэтому убедитесь, что все указано правильно и что сборка / GAC обновлена ​​с помощью хорошей dll.


0

У меня была эта проблема на моем тестовом сервере, потому что я запускал две копии одного и того же wcf в одном пуле приложений. Для меня было решено создать отдельные пулы для каждой версии на моем wcf и после этого перезапустить IIS.


0

Для тех , кто использует NodeJS с Аксиос , чтобы сделать запросы SOAP вы должны включать в себя SOAPAction header. Посмотрите пример ниже:

axios.post('https://wscredhomosocinalparceria.facilinformatica.com.br/WCF/Soap/Emprestimo.svc?wsdl',
           xmls,
  {headers:
  {
    'Content-Type': 'text/xml',
    SOAPAction: 'http://schemas.facilinformatica.com.br/Facil.Credito.WsCred/IEmprestimo/CalcularPrevisaoDeParcelas'}
  }).then(res => {
    console.log(res)
  }).catch(err => {
    console.log(err.response.data)
  })
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.