2010-05-10 5 views
6

J'implémente un service Web WCF qui interagit avec un client dont je ne contrôle pas le code. Le WSDL a été fourni par le client.WSDL premier serveur WCF où le client n'envoie pas SOAPAction

J'ai généré des fichiers C# à partir du WSDL en utilisant SvcUtil, et en plus des erreurs discutées here je n'ai eu aucun problème. Après avoir hébergé le service dans IIS 7.0 avec SSL activé (requis par le client), j'ai tenté d'amener le client à faire une demande au service.

À ce stade, j'ai eu l'erreur suivante:

The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None). 

Je vérifiais que je pouvais utiliser les métadonnées publiées par le service ainsi que SoapUI pour faire la même demande. Cela a bien fonctionné. J'ai ensuite essayé d'utiliser SOAPUI en utilisant le WSDL fourni avec le client. Cela a échoué avec la même erreur d'action vide ci-dessus. J'ai ensuite connecté Wireshark (activation du décryptage SSL) et vérifié que le message envoyé par le client ne contient pas de SOAPAction, il semble donc que ce soit définitivement le problème.

Comme je ne peux pas changer le client est-il un moyen d'obtenir un service Web WCF pour interagir avec un tel client? Je devine qu'il devrait accepter des demandes sans SOAPAction et dériver à la place la demande désirée du type de l'objet de demande dans l'enveloppe SOAP?

Répondre

18

Ce qui suit a fonctionné pour moi (basé sur fil this):

  1. Téléchargez les exemples Microsoft WCF.
  2. Ajoutez les fichiers suivants à votre projet de WF_WCF_Samples \ WCF \ Extensibilité \ Interop \ RouteByBody \ CS \ Service
    • DispatchByBodyOperationSelector.cs
    • DispatchByBodyBehaviorAttribute.cs
  3. Ajoutez les attributs suivants à votre interface (à côté de votre ServiceContract)
    • XmlSerializerFormat
    • DispatchByBodyBehavior
  4. Ajouter ce qui suit à votre interface de service

    [OperationContract(Action = "")] 
    public void DoNothing() 
    { 
    } 
    
  5. Pour mon service le WrapperName et Wrappernamespace sont null pour tous les messages. Je devais aller dans DispatchByBodyBehaviorAttribute et modifier ApplyDispatchBehavior() ajouter les lignes suivantes pour vérifier ceci:

    if (qname.IsEmpty) { 
        qname = new XmlQualifiedName(operationDescription.Messages[0].Body.Parts[0].Name, operationDescription.Messages[0].Body.Parts[0].Namespace); 
    } 
    
+0

SPOT ON! Je viens de passer quelques heures à étudier ce problème. J'essayais de rendre mon nouveau service Web WCF identique (du point de vue du client) à un service Web plus ancien et j'étais vraiment bloqué à ce sujet. J'ai dû spécifier plusieurs actions vides pour obtenir le wsdl pour correspondre à l'ancienne version, mais cela a cassé WCF.C'est, jusqu'à ce que j'ai trouvé votre réponse qui a fonctionné parfaitement. Si je pouvais t'avoir plus d'une fois, je le ferais! –

+0

Content de pouvoir aider. –

+0

Dans le cas où quelqu'un implémente cette solution, et commence à obtenir l'erreur "Ce message ne peut pas supporter l'opération car il a été lu" lors du débogage, voir ma réponse ici qui pourrait aider: http://stackoverflow.com/a/11170390/ 1373170 –

Questions connexes