Niezgodność ContractFilter w wyjątku EndpointDispatcher

116

Mam następujący scenariusz, który próbuję przetestować:

  1. Powszechny WSDL
  2. Punkt końcowy programu WCF, który implementuje obiekty na podstawie WSDL i jest hostowany w usługach IIS.
  3. Aplikacja kliencka, która używa serwera proxy opartego na WSDL do tworzenia żądań.

Kiedy wykonuję wywołanie usługi sieci Web z klienta do punktu końcowego usługi, otrzymuję następujący wyjątek:

{"Wiadomość z akcją ' http: // IMyService / CreateContainer ' nie może zostać przetworzona u odbiorcy z powodu niezgodności ContractFilter w EndpointDispatcher. Może to być spowodowane niezgodnością umowy (niezgodne działania między nadawcą a odbiorcą) lub niezgodność wiązania / bezpieczeństwa między nadawcą a odbiorcą. Sprawdź, czy nadawca i odbiorca mają tę samą umowę i to samo powiązanie (w tym wymogi bezpieczeństwa, np. wiadomość, transport, brak). "}

Zacząłem używać MS Service Trace Viewer, ale nie jestem pewien, gdzie szukać. Patrząc na klasy w kliencie i punkcie końcowym, wyglądają identycznie.

Jak zacząć debugować ten problem?

Jakie są możliwe przyczyny tego wyjątku?

laconicdev
źródło

Odpowiedzi:

75

„Niezgodność filtru ContractFilter w EndpointDispatcher” oznacza, że ​​odbiorca nie mógł przetworzyć komunikatu, ponieważ nie pasuje on do żadnego kontraktu skonfigurowanego przez odbiorcę dla punktu końcowego, który odebrał komunikat.

Może tak być, ponieważ:

  • Masz różne umowy między klientem a nadawcą.
  • Używasz innego powiązania między klientem a nadawcą.
  • Ustawienia zabezpieczeń wiadomości nie są spójne między klientem a nadawcą.

Zajrzyj do EndpointDispatcherklasy, aby uzyskać więcej informacji na ten temat.

Więc:

Upewnij się, że umowy klienta i serwera są zgodne.

  • Jeśli wygenerowałeś swojego klienta z WSDL, czy WSDL jest aktualny?
  • Jeśli ostatnio dokonałeś zmiany w umowie, czy wdrożyłeś odpowiednią wersję zarówno klienta, jak i serwera?
  • Jeśli ręcznie utworzyłeś klasy kontraktów klienta, upewnij się, że przestrzenie nazw, nazwy elementów i nazwy akcji są zgodne z oczekiwanymi przez serwer.

Sprawdź, czy powiązania są takie same między klientem a serwerem.

  • Jeśli używasz pliku .config do zarządzania punktami końcowymi, upewnij się, że elementy powiązania są zgodne.

Sprawdź, czy ustawienia zabezpieczeń są takie same między klientem a serwerem.

  • Jeśli używasz pliku .config do zarządzania punktami końcowymi, upewnij się, że elementy zabezpieczeń są zgodne.
Paul Turner
źródło
3
upewnij się również, że atrybut usługi jest poprawny w pliku .svc. Zobacz moją odpowiedź poniżej.
AntonK,
Chciałem tylko dodać do powyższego rozwiązania (dla nowicjuszy), ponieważ napotkałem ten sam problem, ale powyższe rozwiązanie nie działa dla mnie. Jeśli już wypróbowałeś powyższe obejścia i nadal otrzymujesz ten sam błąd, spróbuj zaktualizować konfigurację przez proste przepisanie punktów końcowych, mimo że jest już poprawna zarówno na serwerze, jak i kliencie.
devpro101
75

Miałem ten błąd i był on spowodowany tym, że umowa odbiorcy nie implementowała wywoływanej metody. Zasadniczo ktoś nie wdrożył najnowszej wersji usługi WCF na serwerze hosta.

Adam
źródło
13
+1 - To samo przytrafiło się mnie, z tym że w moim przypadku to ja byłem tym „kimś”. Zapomniałem zatwierdzić i wdrożyć kod po stronie serwera.
Jesse Webb
2
Tak, źle podałem nazwę akcji SOAP. Chciał tempuri.org/ICodeGenService/RenderApp , ale z jakiegoś powodu kod, który analizował WSDL, myślał, że po prostu tempuri.org/RenderApp .
user435779
Ja też. Miałem metodę w moim .SVC.CS, ale nie ma odpowiadającej jej OperationContract w moim interfejsie.
PahJoker
Ja też :) Odświeżyłem WSDL w SoapUI, korzystając z rozwijanej usługi lokalnej, a gdy utworzyłem żądanie dotyczące nowej metody w usłudze, SoapUI wykorzystało nasze środowisko programistyczne. Więc metoda działała dobrze, po prostu odpytałem zły adres URL.
Larsbj
2
Dzięki! Nie spędzałem godzin na debugowaniu, zamiast tego po przeczytaniu tego szybko zdałem sobie sprawę, że wysyłam żądania do niewłaściwego środowiska.
Jan Matousek
20

Otrzymasz to również, jeśli spróbujesz połączyć się z niewłaściwym adresem URL ;)

Mam dwa punkty końcowe i usługi zdefiniowane w moim systemie o podobnych nazwach.

Otrzymałem dokładnie ten błąd, gdy w pewnym momencie adresy URL zostały zamienione na moim kliencie. Naprawdę podrapał się po głowie, aż w końcu odkryłem ten głupi błąd.

Brady Moritz
źródło
3
To z pewnością głupi błąd, ale tutaj bardzo przydatna odpowiedź. Ponieważ jest to coś oczywistego, łatwo go przeoczyć.
mungflesh
Błędny adres URL wskazuje - błąd „Nie było nasłuchiwania punktu końcowego”
AriesConnolly
20

Miałem ten problem i stwierdziłem, że w moim generatorze proxy, który skopiowałem z innej usługi, zapomniałem zmienić nazwy usługi.

Zmieniłem to ...

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

do...

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

Był to prosty błąd kodu, ale debugowanie było prawie niemożliwe. Mam nadzieję, że zaoszczędzi to komuś czasu.

Obrabować
źródło
To też był mój przypadek.
Vasyl Boroviak
Dzięki, miałem ten sam problem!
Dieterg
10

Dla klienta Java wywołującego punkt końcowy .net. Było to spowodowane niedopasowaniem nagłówka Soap Action.

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

Powyższy nagłówek HTTP lub następujący po nim tag XML musi pasować do akcji / metody, którą próbujesz wywołać.

   <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>
chinto
źródło
9

Rozwiązałem to, dodając do realizacji mojego kontraktu:

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]

Na przykład:

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

}
ben
źródło
To rozwiązało mój problem z przekierowanym portem. Dziękuję Ci.
Mathias Müller
Nie mam nowego błędu, nienawidzę IIS - CommunicationException: serwer nie dostarczył sensownej odpowiedzi; może to być spowodowane niedopasowaniem umowy, przedwczesnym zamknięciem sesji lub wewnętrznym błędem serwera.
AriesConnolly
8

Otrzymałem to po skopiowaniu pliku svc i zmianie jego nazwy. Chociaż nazwa pliku i plik svc.cs zostały poprawnie zmienione, znaczniki nadal odnosiły się do oryginalnego pliku.

Aby to naprawić, kliknij prawym przyciskiem myszy skopiowany plik svc i wybierz opcję Wyświetl znaczniki i zmień odniesienie do usługi.

nic nie wiem
źródło
5

Jak wspomniano w innych odpowiedziach, takich jak @chinto, dzieje się tak, gdy element nagłówka SOAP: Action nie jest zgodny z punktem końcowym.

Aby znaleźć właściwy identyfikator URI, należy spojrzeć na kod WSDL serwera. Zobaczysz element operation z elementem potomnym input, który ma atrybut „Action”. To jest to, co twój SOAP: Action musi być na żądanie klienta.

<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>
Carson Evans
źródło
po dniach googlowania, testowania i wariowania - ta odpowiedź mi pomogła. dzięki.
babboon
w moim konkretnym scenariuszu wywoływałem usługę WebService z mojej klasy java przy użyciu Apache HttpClient. Aby ustawić nagłówek akcji Soap, wywołałem metodę HttpPost SetHeader zaraz po wywołaniu metody setHeader na setContent Type.
vofili
3

Miałem ten sam problem. Problem polegał na tym, że skopiowałem kod z innej usługi jako punkt wyjścia i nie zmieniłem klasy usługi w pliku .svc

Otwórz plik SVC i upewnij się, że atrybut usługi jest poprawny.

 <%@ ServiceHost Language="C#" Debug="true" Service="SME.WCF.ApplicationServices.ReportRenderer" CodeBehind="ReportRenderer.svc.cs" %>
AntonK
źródło
2

Błąd mówi, że istnieje niezgodność, zakładając, że masz wspólny kontrakt oparty na tym samym WSDL, a następnie niezgodność występuje w konfiguracji.

Na przykład, że klient używa nettcpip, a serwer jest skonfigurowany do używania podstawowego protokołu http.

Shiraz Bhaiji
źródło
2

Miałem podobny błąd. Może to być spowodowane zmianą niektórych ustawień kontraktu w pliku konfiguracyjnym po ponownym wprowadzeniu go do projektu. rozwiązanie - zaktualizuj odwołanie do usługi internetowej w swoim projekcie VSstudio lub utwórz nowy serwer proxy za pomocą svcutil.exe

Mahesh Kurup
źródło
1

Ten błąd zwykle pojawia się, jeśli kod nie jest prawidłowo wdrożony.

W moim przypadku mam dwie usługi ServiceA i ServiceB. Znalazłem problem polegający na tym, że pliki ServiceB nie zostały poprawnie wdrożone. Z tego powodu, gdy ServiceA dzwonił wewnętrznie do ServiceB, podawał poniższy błąd.

**Błąd**

Upewnij się, że pliki i odniesienia zostały prawidłowo wdrożone.

Atul K.
źródło
1

Spędziłem dni szukając odpowiedzi i znalazłem ją, ale nie w tym wątku. Jestem bardzo nowy w WCF i C #, więc dla niektórych odpowiedź może być oczywista.

W mojej sytuacji miałem narzędzie klienckie, które zostało pierwotnie opracowane dla usługi ASMX i dla mnie zwracało ten sam komunikat o błędzie.

Po wypróbowaniu różnych rekomendacji znalazłem tę stronę:

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

Postawiło mnie to na właściwej ścieżce. W szczególności „soap: operation” - WCF dołączał ServiceName do Namespace:

klient oczekiwany Http://TEST.COM/Login, ale wysłano WCF Http://TEST.COM/IService1/Login. Rozwiązaniem jest dodanie takich ustawień [OperationContract]:

[OperationContract(Action = "http://TEST.COM/Login", ReplyAction = "http://TEST.COM/Login")] (Ignoruj ​​spacje w HTTP)

KSNSACC
źródło
2
Dobrze. Twoim rozwiązaniem jest zachowanie usługi zgodnie z oczekiwaniami niektórych klientów. Ale można to równie dobrze (lub w wielu przypadkach najlepiej) rozwiązać poprzez faktyczne dostosowanie się klienta do umowy z serwerem! Przecież serwer jest wydawcą umowy.
The Dag,
1

Może to wynikać z 2 powodów:

  1. numer referencyjny usługi jest nieaktualny, kliknij prawym przyciskiem myszy numer referencyjny usługi n zaktualizuj go.

  2. umowa, którą wdrożyłeś, może różnić się od tego, co ma klient. Porównaj obie usługi n kontrakt klienta n napraw niezgodność umów.

Abdul sami
źródło
1

Jeśli wywołujesz metodę WCF, powinieneś dołączyć interfejs w nagłówku.

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+ "\"");
}
Ahmet Arslan
źródło
1

Może to być również przydatne dla tych, którzy robią to przez kodowanie. Musisz dodać WebHttpBehavior () do dodanego punktu końcowego usługi. Coś jak:

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

Spójrz na: https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/calling-a-rest-style-service-from-a-wcf-service

Amir Dashti
źródło
To pomogło mi zaoszczędzić czas, dzięki :)
Sely Lychee
0

Głupie, ale zapomniałem dodać [OperationContract]do mojego interfejsu serwisowego (tego oznaczonego [ServiceContract]) i wtedy też pojawia się ten błąd.

Piotr
źródło
0

Twój klient nie został zaktualizowany, więc zaktualizuj swoje usługi z usługi sieci Web, a następnie odbuduj projekt

Masoud Bahrami
źródło
0

Ja też miałem ten problem. Okazało się, że było to spowodowane serializatorem kontraktu po stronie serwera. Nie mógł zwrócić obiektu kontraktu danych, ponieważ niektóre jego elementy składowe danych były właściwościami tylko do odczytu .

Upewnij się, że obiekty mają metody ustawiające właściwości przeznaczone do serializacji.

Crono
źródło
0

Co dziwne, obejdzieliśmy ten błąd, używając tej samej wielkości liter, co nazwa Path i OperationContract. Najwyraźniej rozróżniano wielkość liter. Jeśli ktoś wie dlaczego, proszę o komentarz. Dziękuję Ci!

MikeTeeVee
źródło
0

Tak więc mój przypadek był następujący. Nie używałem proxy do interakcji klient-serwer, korzystałem z ChannelFactory (dlatego wszystkie rady dotyczące aktualizacji do odniesienia do usługi były dla mnie bez znaczenia).

Usługa była hostowana w usługach IIS iz jakiegoś powodu miała nieprawidłowe odwołania w folderze bin. Rekompilacja projektu po prostu nie doprowadziła do powstania nowych bibliotek dll w tym folderze.

Po prostu usunąłem stamtąd wszystkie rzeczy i dodałem odniesienie do usługi w tym samym rozwiązaniu, a następnie ponownie skompilowałem i teraz wszystko działa.

psfinaki
źródło
0

Mój problem okazał się czymś rzadkim, ale i tak o nim wspomnę.

Napotkałem problem podczas wdrażania w naszym środowisku programistycznym. Na tym komputerze nasz budowniczy utworzył dwa foldery (wdrożył dwie aplikacje). Stara wersja i nowa aktualna wersja. Więc jeśli nie masz dwóch wersji swojej aplikacji na serwerze internetowym, nie dotyczy to Ciebie.

Nowa lokalizacja, którą utworzył, miała niestandardową nazwę jako pierwszą część adresu URL po hoście:

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

Na moim komputerze lokalnym mój klient wskazywał na standardową nazwę folderu skonfigurowaną we wszystkich środowiskach (z wyjątkiem programowania), w tym w moim środowisku lokalnym.

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

Kiedy oderwałem się i zastąpiłem web.config podczas programowania moją lokalną kopią, część adresu URL, która musiała być specjalna, została zdmuchnięta częścią standardową, w wyniku czego klient na dev wskazał starą aplikację.

Stara aplikacja miała starą umowę i nie zrozumiała żądania i wyrzuciła ten błąd.

toddmo
źródło
0

Wystąpił ten sam błąd we wdrożonej usłudze WCF, problem był związany z inną usługą wdrożoną z inną umową z tym samym portem.

Rozwiązanie

Użyłem różnych portów w web.config i problem zniknął.

Usługa 1

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

Usługa 2

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

Również natknąłem się na tę sytuację, używając innego portu dla tego samego adresu między usługą a konsumentem.

DanielV
źródło
0

Wystąpił ten błąd, ponieważ mam starą wersję biblioteki DLL w GAC mojego serwera. Więc upewnij się, że wszystko jest poprawnie przywoływane i że zestaw / GAC jest aktualny z dobrą biblioteką dll.

Helpha
źródło
0

Miałem ten problem na moim serwerze testowym, ponieważ uruchomiłem dwie kopie tego samego programu WCF w tej samej puli aplikacji. Rozwiązaniem dla mnie było utworzenie oddzielnych pul dla każdej wersji na moim WCF i ponowne uruchomienie IIS po tym.

Johann
źródło
0

Dla tych, którzy używają NodeJS z axios do wysyłania żądań SOAP, musisz dołączyć plik SOAPAction header. Sprawdź poniższy przykład:

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)
  })
Christian Saiki
źródło