6

I am implementing a WCF web service which interacts with a client whose code I do not control. The WSDL was supplied by the client.

I generated C# files from the WSDL using SvcUtil, and besides the errors discussed here I had no issues.

After hosting the service in IIS 7.0 with SSL enabled (required by the client) I attempted to get the client to make a request to the service.

At this point I got the following error:

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

I verified that I could use the metadata published by the service along with SOAPUI to make the same request. This worked fine.

I then attempted to use SOAPUI using the WSDL supplied with the client. This failed with the same empty action error above.

I then hooked up Wireshark (enabling SSL decryption) and verified that the message sent from the client indeed lacks a SOAPAction, so it appears that this is definitely the issue.

As I cannot change the client is there a way to get a WCF web service to interact with such a client? I'm guessing it would need to accept requests with no SOAPAction and instead derive the desired request from type of the request object in the SOAP envelope?

Redwood
  • 66,744
  • 41
  • 126
  • 187

1 Answers1

19

The following worked for me (based on this thread):

  1. Download the Microsoft WCF examples.
  2. Add the following files to your project from WF_WCF_Samples\WCF\Extensibility\Interop\RouteByBody\CS\service
    • DispatchByBodyOperationSelector.cs
    • DispatchByBodyBehaviorAttribute.cs
  3. Add the following attributes to your interface (next to your ServiceContract)
    • XmlSerializerFormat
    • DispatchByBodyBehavior
  4. Add the following to your service interface

    [OperationContract(Action = "")]
    public void DoNothing()
    {
    }
    
  5. For my service the WrapperName and Wrappernamespace are null for all messages. I had to go into DispatchByBodyBehaviorAttribute and edit ApplyDispatchBehavior() to add the following lines to check for this:

     if (qname.IsEmpty) {
         qname = new XmlQualifiedName(operationDescription.Messages[0].Body.Parts[0].Name, operationDescription.Messages[0].Body.Parts[0].Namespace);
     }
    
Redwood
  • 66,744
  • 41
  • 126
  • 187
  • SPOT ON! I've just spent a few hours looking into this issue. I was trying to make my new WCF web service look identical (from a client perspective) to an older web service and was really stuck on this. I had to specify multiple empty actions to get the wsdl to match the old version, but this broke WCF. That is, until I found your answer which worked perfectly. If I could upvote you more than once, I would! – Rob Levine Jul 20 '10 at 18:00
  • In case anybody implements this solution, and starts getting the error "This message cannot support the operation because it has been read" when debugging, see my response here that might help: http://stackoverflow.com/a/11170390/1373170 – Pablo Romeo Jun 23 '12 at 14:52
  • works great! But now my wsdl page is broken.. someone have any idea? – Sérgio S. Filho Mar 25 '14 at 14:37
  • Just saved my bacon! I had consumed a WSDL using SvcUtil.exe that was for a Java based web service. It generated identical Action attributes for different method calls, which WCF does not like. This solution enabled it to work so I could Emulate the Java service! Thanks! – Pratt Hinds Jun 19 '17 at 16:40