Incompatibilité de ContractFilter au niveau de l'exception EndpointDispatcher


116

J'ai le scénario suivant que j'essaie de tester:

  1. Un WSDL commun
  2. Point de terminaison WCF qui implémente des objets basés sur le WSDL et est hébergé dans IIS.
  3. Une application cliente qui utilise un proxy basé sur WSDL pour créer des demandes.

Lorsque je passe un appel de service Web du client au point de terminaison du service, j'obtiens l'exception suivante:

{"Le message avec l'action ' http: // IMyService / CreateContainer ' ne peut pas être traité au niveau du destinataire, en raison d'une incompatibilité de ContractFilter au niveau d'EndpointDispatcher. Cela peut être dû à une incompatibilité de contrat (actions incompatibles entre l'expéditeur et le destinataire) ou à un non-concordance de liaison / sécurité entre l'expéditeur et le destinataire. Vérifiez que l'expéditeur et le destinataire ont le même contrat et la même liaison (y compris les exigences de sécurité, par exemple Message, Transport, Aucun). "}

J'ai commencé à utiliser MS Service Trace Viewer, mais je ne sais pas où chercher. Tout en regardant les classes dans le client et le point de terminaison, elles semblent identiques.

Comment déboguer ce problème?

Quelles sont les causes possibles de cette exception?

Réponses:


75

Une «incompatibilité ContractFilter au niveau de l'EndpointDispatcher» signifie que le destinataire n'a pas pu traiter le message car il ne correspond à aucun des contrats que le destinataire a configurés pour le terminal qui a reçu le message.

Cela peut être dû au fait que:

  • Vous avez des contrats différents entre le client et l'expéditeur.
  • Vous utilisez une liaison différente entre le client et l'expéditeur.
  • Les paramètres de sécurité des messages ne sont pas cohérents entre le client et l'expéditeur.

Regardez la EndpointDispatcherclasse pour plus d'informations sur le sujet.

Alors:

Assurez-vous que vos contrats client et serveur correspondent.

  • Si vous avez généré votre client à partir d'un WSDL, le WSDL est-il à jour?
  • Si vous avez récemment modifié le contrat, avez-vous déployé la bonne version du client et du serveur?
  • Si vous avez créé à la main vos classes de contrat client, assurez-vous que les espaces de noms, les noms d'éléments et les noms d'actions correspondent à ceux attendus par le serveur.

Vérifiez que les liaisons sont les mêmes entre le client et le serveur.

  • Si vous utilisez un fichier .config pour gérer vos points de terminaison, assurez-vous que les éléments de liaison correspondent.

Vérifiez que les paramètres de sécurité sont les mêmes entre le client et le serveur.

  • Si vous utilisez un fichier .config pour gérer vos points de terminaison, assurez-vous que les éléments de sécurité correspondent.

3
assurez-vous également que l'attribut de service est correct dans le fichier .svc. Voir ma réponse ci-dessous.
AntonK

Je voulais juste ajouter à la solution ci-dessus (pour les nouveaux arrivants) car j'ai rencontré le même problème mais la solution ci-dessus n'a pas fonctionné pour moi. Si vous avez déjà essayé les solutions de contournement ci-dessus et que vous obtenez toujours la même erreur, essayez de mettre à jour votre configuration en retapant simplement les points de terminaison impliqués, même si c'est déjà correct sur le serveur et le client.
devpro101

75

J'ai eu cette erreur et cela a été causé par le contrat du recevier qui n'implémente pas la méthode appelée. Fondamentalement, quelqu'un n'avait pas déployé la dernière version du service WCF sur le serveur hôte.


13
+1 - La même chose m'est arrivée, sauf que dans mon cas c'était moi qui étais le "quelqu'un". J'avais oublié de valider et déployer le code côté serveur.
Jesse Webb

2
Ouais, j'avais mal le nom de l'action SOAP. Il voulait tempuri.org/ICodeGenService/RenderApp , mais pour une raison quelconque, le code qui analysait le WSDL ne pensait qu'à tempuri.org/RenderApp .
user435779

Moi aussi. J'avais la méthode dans mon .SVC.CS, mais aucun OperationContract correspondant dans mon interface.
PahJoker

Moi aussi :) J'ai rafraîchi le WSDL dans SoapUI en utilisant le service local en cours de développement, et quand j'ai créé une requête contre la nouvelle méthode du service, SoapUI a utilisé notre environnement de développement. Donc, la méthode fonctionnait bien, je viens de demander la mauvaise URL.
Larsbj

2
Merci! Je n'ai pas passé des heures à déboguer, mais après avoir lu ceci, j'ai rapidement réalisé que j'envoyais des demandes à un mauvais environnement.
Jan Matousek

20

Vous obtiendrez également ceci si vous essayez de vous connecter à la mauvaise URL ;)

J'ai deux points de terminaison et services définis dans mon système, avec des noms similaires.

Vous avez cette erreur exacte lorsque les URL ont été échangées sur mon client à un moment donné. Vraiment griffé la tête jusqu'à ce que finalement cette erreur stupide se comprenne.


3
C'est une erreur stupide à faire avec certitude, mais une réponse très utile ici. Comme c'est quelque chose d'évident, il est facilement négligé.
mungflesh

Mauvaise URL donne - erreur `` il n'y avait pas d'écoute de point de terminaison ''
AriesConnolly

20

J'ai eu ce problème et j'ai trouvé que dans mon générateur de proxy, que j'ai copié à partir d'un autre service, j'ai oublié de changer le nom du service.

J'ai changé ça ...

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

à...

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

C'était une simple erreur de code, mais presque impossible à déboguer. J'espère que cela fera gagner du temps à quelqu'un.


C'était aussi mon cas.
Vasyl Boroviak

Merci, j'ai eu le même problème!
Dieterg

10

Pour un client Java appelant un point de terminaison .net. Cela était dû à une incompatibilité de l'en-tête Soap Action.

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

L'en-tête HTTP ci-dessus ou la balise XML suivante doit correspondre à l'action / méthode que vous essayez d'appeler.

   <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

J'ai résolu ce problème en ajoutant ce qui suit à la mise en œuvre de mon contrat:

[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]

Par exemple:

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

}

Cela a résolu mon problème avec un port transféré. Je vous remercie.
Mathias Müller

Non j'ai eu une nouvelle erreur, je déteste IIS - CommunicationException: Le serveur n'a pas fourni de réponse significative; cela peut être dû à une incompatibilité de contrat, à un arrêt prématuré de session ou à une erreur interne du serveur.
AriesConnolly

8

Je l'ai obtenu après avoir copié le fichier svc et l'avoir renommé. Bien que le nom de fichier et le fichier svc.cs aient été correctement renommés, le balisage faisait toujours référence au fichier d'origine.

Pour résoudre ce problème, cliquez avec le bouton droit sur le fichier svc copié et choisissez Afficher le balisage et modifiez la référence du service.


5

Comme mentionné dans d'autres réponses, telles que @chinto, cela se produit lorsque l'élément d'en-tête SOAP: Action ne correspond pas au point de terminaison.

Vous pouvez trouver l'URI correct à utiliser en regardant le WSDL du serveur. Vous verrez un élément d'opération avec un enfant d'entrée qui a un attribut "Action". C'est ce que votre SOAP: Action doit être sur la demande du client.

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

après des jours de recherche sur Google et de tests et de devenir fou - cette réponse m'a aidé. Merci.
babboon

dans mon scénario particulier, je faisais l'appel au WebService à partir de ma classe java en utilisant Apache HttpClient. Afin de définir l'en-tête d'action Soap, j'ai appelé la méthode HttpPost SetHeader juste après avoir appelé la méthode setHeader sur setContent Type.
vofili

3

J'ai eu le même problème. Le problème était que j'ai copié le code d'un autre service comme point de départ et que je n'ai pas changé la classe de service dans le fichier .svc

Ouvrez le fichier .svc et assurez-vous que l'attribut Service est correct.

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

2

L'erreur indique qu'il y a une incompatibilité, en supposant que vous avez un contrat commun basé sur le même WSDL, alors l'incohérence se trouve dans la configuration.

Par exemple, le client utilise nettcpip et le serveur est configuré pour utiliser http de base.


2

J'ai eu une erreur similaire. Cela peut être dû au fait que vous auriez modifié certains paramètres de contrat sur votre fichier de configuration après qu'il ait été réfracté dans votre projet. solution - Mettez à jour la référence du service Web sur votre projet VSstudio ou créez un nouveau proxy à l'aide de svcutil.exe


1

Cette erreur survient généralement si le code n'est pas déployé correctement.

Dans mon cas, j'ai deux services ServiceA et ServiceB. J'ai trouvé le problème que les fichiers ServiceB n'étaient pas déployés correctement. À cause de cela, lorsque ServiceA appelait ServiceB en interne, il donnait l'erreur ci-dessous.

**Erreur**

Veuillez vous assurer que les fichiers et les références sont correctement déployés.


1

J'ai passé des jours à chercher la réponse et je l'ai trouvée, mais pas dans ce fil. Je suis très nouveau dans WCF et C #, donc pour certains, la réponse pourrait être évidente.

Dans ma situation, j'avais un outil client qui a été initialement développé pour le service ASMX, et pour moi, il renvoyait le même message d'erreur.

Après avoir essayé toutes sortes de recommandations, j'ai trouvé ce site:

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

Cela m'a mis sur la bonne voie. Plus précisément "soap: operation" - WCF ajoutait ServiceName à l'espace de noms:

client attendu Http://TEST.COM/Login, mais WCF envoyé Http://TEST.COM/IService1/Login. La solution consiste à ajouter un paramètre à[OperationContract] comme ceci:

[OperationContract(Action = "http://TEST.COM/Login", ReplyAction = "http://TEST.COM/Login")] (Ignorer les espaces vides dans Http)


2
Bien. Votre solution consiste à faire en sorte que le service se comporte comme l'attend certains clients. Mais il pourrait tout aussi bien (ou dans de nombreux cas, de préférence) être résolu en faisant en sorte que le client se conforme réellement au contrat du serveur! Après tout, le serveur est l'éditeur du contrat.
The Dag du

1

Cela pourrait être pour 2 raisons à cela:

  1. la référence du service est obsolète, cliquez avec le bouton droit sur la référence du service pour la mettre à jour

  2. le contrat que vous avez mis en œuvre peut être différent de celui du client. Comparez les deux services n contrat client n corrigez la non-concordance des contrats.


1

Si vous appelez la méthode WCF, vous devez inclure l'interface dans Header.

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

Cela pourrait également être utile pour ceux qui font cela en codant. Vous devez ajouter WebHttpBehavior () à votre point de terminaison de service ajouté. Quelque chose comme:

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

Jetez un œil à: https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/calling-a-rest-style-service-from-a-wcf-service


Cela m'a aidé à gagner du temps, merci :)
Sely Lychee

0

Idiot, mais j'ai oublié d'ajouter [OperationContract]à mon interface de service (celle marquée avec [ServiceContract]) et vous obtenez également cette erreur.


0

Votre client n'a pas été mis à jour, alors mettez à jour vos services à partir du service Web puis reconstruisez votre projet


0

J'ai eu ce problème aussi. Il s'est avéré que cela avait été causé par le sérialiseur de contrat du côté du serveur. Il n'a pas pu renvoyer mon objet de contrat de données car certains de ses membres de données étaient des propriétés en lecture seule .

Assurez-vous que vos objets ont des setters pour les propriétés destinées à être sérialisées.


0

Curieusement, nous avons contourné cette erreur en utilisant la même casse que le nom Path et OperationContract utilisé. Apparemment, c'était sensible à la casse. Si quelqu'un sait pourquoi, veuillez commenter. Je vous remercie!


0

Donc, mon cas était le suivant. Je n'ai pas utilisé de proxy pour l'interaction client-serveur, j'ai utilisé ChannelFactory (donc tous les conseils de mise à niveau vers la référence de service n'avaient aucun sens pour moi).

Le service était hébergé dans IIS et pour une raison quelconque, il avait des références erronées dans le dossier bin. La recompilation du projet n'a tout simplement pas conduit à de nouvelles dll dans ce dossier.

J'ai donc simplement supprimé tous les éléments à partir de là et ajouté une référence au service dans la même solution, puis recompilé et maintenant tout fonctionne.


0

Mon problème s'est avéré être quelque chose de rare, mais je le mentionnerai quand même.

J'ai rencontré le problème de déploiement dans notre environnement de développement. Sur cette machine, notre personne de construction avait créé deux dossiers (déployé deux applications). Une ancienne version et la nouvelle version actuelle.Donc, si vous n'avez pas deux versions de votre application sur le serveur Web, cela ne s'applique pas à vous.

Le nouvel emplacement qu'il a créé avait un nom non standard dans la première partie de l'url après l'hôte:

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

Sur ma machine locale, mon client pointait vers le nom de dossier standard tel qu'il était configuré sur tous les environnements (sauf le développement), y compris mon environnement local.

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

Quand j'ai été époustouflé et que j'ai remplacé le web.config lors du développement par ma copie locale, la partie de l'url qui devait être spéciale a été époustouflée par la partie standard, de sorte que le client sur dev a pointé vers l'ancienne application.

L'ancienne application avait un ancien contrat et n'a pas compris la demande et a renvoyé cette erreur.


0

J'ai eu la même erreur sur un service WCF déployé, le problème était lié à un autre service déployé avec un autre contrat avec le même port.

Solution

J'ai utilisé différents ports dans le web.config et le problème a disparu.

Service 1

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

Service 2

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

De plus , j'ai rencontré cette situation en utilisant un port différent pour la même adresse entre le service et le consommateur.


0

J'ai eu cette erreur car j'ai une ancienne version de la DLL dans le GAC de mon serveur. Assurez-vous donc que tout est correctement référencé et que l'assembly / GAC est à jour avec la bonne dll.


0

J'ai eu ce problème sur mon serveur de test, car j'exécutais deux copies du même wcf sur le même pool d'applications. Ce qui a été résolu pour moi a été de créer des pools séparés pour chaque version sur mon WCF et de redémarrer l'IIS après cela.


0

Pour ceux qui utilisent NodeJS avec axios pour effectuer les requêtes SOAP, vous devez inclure un fichier SOAPAction header. Consultez l'exemple ci-dessous:

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)
  })
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.