Search code examples
.netsoapwcf-binding

Visual Studio Service Reference to SOAP WS not working


I have a .NET 4.8 application with a service reference to a SOAP service with WSDL. When I run the login call it fails with a 403 Forbidden.

When I run the request with SoapUI it works fine. The request in SoapUI looks like this:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ser="[DOMAIN]">
   <soap:Header/>
   <soap:Body>
      <ser:login>
         <ser:loginId>xxxx</ser:loginId>
         <ser:password>xxxx</ser:password>
      </ser:login>
   </soap:Body>
</soap:Envelope>

This is the request from the autogenerated client in VS - I catched it with Fiddler:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
    <s:Header>
        <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo92QKpG5BEZEnq6P0sIw0t4AAAAAAh+2S3CUB0COgd1fCDQEOWkvOeoaufVNjSjzFRUDP/gACQAA</VsDebuggerCausalityData>
    </s:Header>
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <login xmlns="[DOMAIN]">
            <loginId>xxxx</loginId>
            <password>xxxx</password>
        </login>
    </s:Body>
</s:Envelope>

So I played with the failed request to find the reason why it is rejected by the server. The VsDebuggerCausalityData element added by VS is no problem. It looks like the server insists on having the namespaces defined at the beginning and the soap elements must have the prefix "soap:" - "s:" does not work.

Is there a way to solve this - without manually writing the SOAP requests?


Solution

  • You can try implementing IClientMessageInspector to modify soap and then see if the service works properly.

    public class ClientMessageInspector : IClientMessageInspector
    {
        // Here we can alter the soap before it gets sent out.
        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            return TibcoService.ModifyGetLocationRequest(ref request);
    
        } // end
    
        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            return;
    
        } //end
    
    }
    

    You may modify the properties of the header or body according to this case to suit your requirements.