简体   繁体   中英

WCF service client: Customized soap envelope not being sent on the wire

I am calling a 3rd party web service from a WCF client. The problem is that the service requires a specific soap envelope format.

The question WCF Soap Format deals with the same problem and the solution suggested was to write a CustomTextMessageEncoder.

I have written a custom message encoder and done my custom formatting in the WriteMessage method taking the MSDN sample encoder as described in the topic http://msdn.microsoft.com/en-us/library/ms751486(v=vs.110).aspx .

The custom formatting removes the soap header content and adds some namespace prefixing required by the 3rd party service.

I can see that the encoder is being called in the VS debugger and that it is producing the desired output:

        public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)
    {
        // code from MSDN example
        MemoryStream stream = new MemoryStream();
        XmlWriter writer = XmlWriter.Create(stream, this.writerSettings);
        message.WriteMessage(writer);
        writer.Close();

        // My customizing code
        var targetStream = new MemoryStream();
        FormatStreamToMirthFormat(stream, targetStream);

        // code from MSDN example
        // put the contents of the stream into a byte array
        byte[] messageBytes = targetStream.GetBuffer();
        int messageLength = (int)targetStream.Position;
        stream.Close();

        int totalLength = messageLength + messageOffset;
        byte[] totalBytes = bufferManager.TakeBuffer(totalLength);
        Array.Copy(messageBytes, 0, totalBytes, messageOffset, messageLength);

        ArraySegment<byte> byteArray = new ArraySegment<byte>(totalBytes, messageOffset, messageLength);
        return byteArray;
    }

I have configured service message tracing in the app.config to see what is actually being sent and the problem I have is that it appears that the incoming soap envelope is still being sent on the wire (the envelope that is being sent when using basicHttpBinding).

Why is the incoming soap envelope and not my custom soap envelope being sent?

The other thing I noticed is if I use the default binding "basicHttpBinding" then the message on the wire contains a Http header followed by the soap envelope:

<HttpRequest xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace">
   <Method>POST</Method>
   <QueryString></QueryString>
   <WebHeaders>
       <VsDebuggerCausalityData>uIDPo+hLJO6ZB9hNt7/+pVZglrYAAAAAus8ogaD9Y0O0ThkjxtbdzBlxO8Yn2yBJggkv3BRx/qsACQAA</VsDebuggerCausalityData>
</WebHeaders>
</HttpRequest>
<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">..

whereas my message starts with the soap envelope.

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">

Thanks for any help.

The MessageEncoder takes place late in the WCF pipeline and you might have problems in the future if additional security requirements need to be implemented. I would recommend a MessageFormatter. Take a look at this article .

It explains how to do this server side, but you can also do it client side in a similar way, by overriding the ApplyClientBehavior instead of ApplyDispatchBehavior, and deriving IClientMessageFormatter instead of IDispatchMessageFormatter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM