Search code examples
wcfsoapwsdl

WSDL first WCF server where client does not send SOAPAction


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?


Solution

  • 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);
       }