web-dev-qa-db-fra.com

Non concordance de ContractFilter à l'exception EndpointDispatcher

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 le WSDL pour créer des demandes. 

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

{"Le message avec Action ' http: // IMyService/CreateContainer ' ne peut pas être traité sur le destinataire, en raison d'une incompatibilité ContractFilter sur EndpointDispatcher. Cela peut être dû à une incompatibilité de contrat (actions incompatibles entre l'expéditeur et le destinataire) ou une incompatibilité de sécurité/engagement 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 obligation (y compris les exigences de sécurité, par exemple Message, Transport, Aucune). "}

J'ai commencé à utiliser MS Service Trace Viewer, mais je ne savais pas où chercher. Lorsque vous examinez les classes dans le client et le noeud final, elles semblent identiques. 

Comment commence-t-on à déboguer ce problème? 

Quelles sont les causes possibles de cette exception?

98
laconicdev

Une "incompatibilité ContractFilter sur EndpointDispatcher" signifie que le destinataire n'a pas pu traiter le message car il ne correspond à aucun des contrats configurés par le destinataire pour le terminal qui a reçu le message.

Cela peut être parce 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.

Consultez la classe EndpointDispatcher 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, noms d'éléments et noms d'action 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.
69
Paul Turner

J'ai eu cette erreur et cela était dû au fait que le contrat du séquestre n'implémentait pas la méthode appelée. En gros, quelqu'un n'avait pas déployé la dernière version du service WCF sur le serveur hôte. 

72
adam

J'ai eu ce problème et j'ai constaté que dans mon générateur de proxy, que j'avais copié depuis un autre service, j'avais 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 fait gagner du temps à quelqu'un.

19
Rob

Vous l'obtiendrez aussi si vous essayez de vous connecter à la mauvaise URL ;) 

Deux systèmes d'extrémité et services sont définis dans mon système, avec des noms similaires. 

Vous avez cette erreur exacte lorsque les URL ont été permutées sur mon client à un moment donné. Vraiment gratté la tête jusqu'à comprendre enfin cette stupide erreur.

17
Brady Moritz

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

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/à la méthode que vous tentez 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
chinto

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
{

}
9
ben

Je l'ai eu après avoir copié le fichier svc et l'ai renommé. Bien que le nom de fichier et le fichier svc.cs aient été renommés correctement, 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.

8
iKnowNothing

J'ai eu le même problème. Le problème était que j'avais copié le code d'un autre service comme point de départ et que je n'avais 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" %>
3
AntonK

Comme indiqué 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 consultant le WSDL du serveur. Vous verrez un élément d'opération avec un enfant d'entrée ayant un attribut "Action". C’est ce que votre SOAP: Action doit être à 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>
3
carsonevans

L'erreur indique qu'il existe une incompatibilité, en supposant que vous ayez un contrat commun basé sur le même WSDL. Cette incompatibilité se trouve dans la configuration.

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

2
Shiraz Bhaiji

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

2
Mahesh Kurup

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 en WCF et en C #, aussi, pour certains, la réponse pourrait être évidente. 

Dans ma situation, j'avais un outil client développé à l'origine 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 le bon chemin. Spécifiquement "soap: operation" - WCF ajoutait ServiceName à l'espace de noms: 

client attendu Http://TEST.COM/Login, mais WCF a 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")] (Ignore les espaces vides dans Http)

1
KSNSACC

Si vous appelez une méthode WCF, vous devez inclure l'interface dans l'en-tête.

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

Cela pourrait être pour 2 raisons: 

  1. service ref est obsolète, clic droit service ref n le mettre à jour.

  2. le contrat que vous avez implémenté peut être différent de ce que le client .__ a. Comparez les deux contrats de service/client n et corrigez les contrats Mismatch.

1
Abdul sami

En outre, il pourrait être utile pour ceux qui le font en codant. Vous devez ajouter WebHttpBehavior () à votre noeud final de service ajouté. Quelque chose comme: 

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

Consultez: https://docs.Microsoft.com/en-us/dotnet/framework/wcf/feature-details/calling-a-rest-style-service-de-ww- un service

1
Amir Dashti

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. En effet, lorsque ServiceA appelait ServiceB en interne, il donnait une erreur ci-dessous.

**Error**

Assurez-vous que les fichiers et les références sont correctement déployés.

0
Atul K.

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

0
Johann

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

0
Peter

J'ai eu ce problème aussi. Il s'est avéré que cela était dû au sérialiseur de contrat du côté du serveur. Il n'a pas pu retourner 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 disposent de paramètres pour les propriétés destinées à être sérialisées.

0
Crono

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

Le service était hébergé dans IIS et pour une raison quelconque, il contenait 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. 

Donc, je viens de supprimer 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
psfinaki

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

Aussi, je me suis heurté à cette situation en utilisant un port différent pour la même adresse entre le service et le consommateur.

0
DanielV

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

0
Masoud Bahrami

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

0
Helpha

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

J'ai rencontré le problème lors du déploiement dans notre environnement de développement. Sur cette machine, notre responsable de la création 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 vous concerne pas.

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

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

Sur mon ordinateur local, mon client pointait sur le nom du dossier standard tel qu'il était configuré sur tous les environnements (à l'exception du développement), y compris mon environnement local.

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

Lorsque je suis parti et que j'ai remplacé le composant web.config sur le développement par ma copie locale, la partie de l'URL devant être spéciale a été balayée par la partie standard, de sorte que le client sur dev a alors dirigé l'ancienne application.

L'ancienne application avait un ancien contrat et ne comprenait pas la demande et renvoyait cette erreur.

0
toddmo

Curieusement, nous avons corrigé cette erreur en utilisant le même boîtier que les noms Path et OperationContract utilisés. Apparemment, il était sensible à la casse. Si quelqu'un sait pourquoi, veuillez commenter. Je vous remercie!

0
MikeTeeVee

Pour ceux qui utilisent NodeJS avec axios pour effectuer les demandes SOAP, vous devez inclure un SOAPAction header. Vérifiez 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)
  })
0
Christian Saiki