9

I have added a wsdl file in my project as a service reference. The application sends SOAP messages to a particular device which then sends the response in SOAP format.

Is there a way to look at the actual SOAP message that is wrapped in XML? Having to turn on wireshark to look at the SOAP messages gets tedious.

TtT23
  • 6,876
  • 34
  • 103
  • 174

5 Answers5

4

You can use the SVCTraceViewer to trace what are the messages that are being sent to and fro for each service call. You just have to set up the config and WCF builds the log files with the .svclog extension.

More details on this tool and its associated configuration is here. This does not require any 3rd party tool or network inspectors to be run etc... This is out of the box from Microsoft.

Saravanan
  • 7,637
  • 5
  • 41
  • 72
  • It worked for me. Tool's path in my PC: **C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\SvcTraceViewer.exe** and Here is an article about using tool: https://patrickdesjardins.com/blog/using-service-trace-viewer-tool-to-debug-wcf-service – Furkan Ekinci Nov 25 '20 at 06:12
3

You are probably looking for SOAP extension, look at this post:

Get SOAP Message before sending it to the WebService in .NET

Community
  • 1
  • 1
Moka
  • 262
  • 1
  • 9
2

Use Fiddler to inspect the messages. Ref: Using fiddler.

S.N
  • 4,910
  • 5
  • 31
  • 51
2

In case of WCF it has a less-known way to intercept original XML - custom MessageEncoder. It works on low level, so it captures real byte content including any malformed xml.

If you want use this approach you need to wrap a standard textMessageEncoding with custom message encoder as new binding element and apply that custom binding to endpoint in your config.

Also there is an example how I did it in my project - wrapping textMessageEncoding, logging encoder, custom binding element and config.

Adam
  • 1,796
  • 18
  • 19
0

I just wrapped the SOAP xml writer method and then inside the method made an event when the writing is flushed:

protected override XmlWriter GetWriterForMessage(SoapClientMessage message, int bufferSize)
{
   VerboseXmlWriter xmlWriter = new VerboseXmlWriter(base.GetWriterForMessage(message, bufferSize));
   xmlWriter.Finished += XmlWriter_Finished;
}

The Class for the VerboseXmlWriter goes like that (just the idea):

public sealed class VerboseXmlWriter : XmlWriter
    {
        private readonly XmlWriter _wrappedXmlWriter;
        private readonly XmlTextWriter _buffer;
        private readonly System.IO.StringWriter _stringWriter;

        public event EventHandler Finished;

        private void OnFinished(StringPayloadEventArgs e)
        {
            EventHandler handler = Finished;
            handler?.Invoke(this, e);
        }

        public VerboseXmlWriter(XmlWriter implementation)
        {
            _wrappedXmlWriter = implementation;
            _stringWriter = new System.IO.StringWriter();
            _buffer = new XmlTextWriter(_stringWriter);
            _buffer.Formatting = Formatting.Indented;
        }

        ~VerboseXmlWriter()
        {
            OnFinished(new StringPayloadEventArgs(_stringWriter.ToString()));
        }

        public override void Flush()
        {
            _wrappedXmlWriter.Flush();
            _buffer.Flush();
            _stringWriter.Flush();
        }

        public string Xml
        {
            get
            {
                return _stringWriter?.ToString();
            }
        }

        public override WriteState WriteState => _wrappedXmlWriter.WriteState;

        public override void Close()
        {
            _wrappedXmlWriter.Close();
            _buffer.Close();
        }
        public override string LookupPrefix(string ns)
        {
            return _wrappedXmlWriter.LookupPrefix(ns);
        }
        public override void WriteBase64(byte[] buffer, int index, int count)
        {
            _wrappedXmlWriter.WriteBase64(buffer, index, count);
            _buffer.WriteBase64(buffer, index, count);
        }

        public override void WriteSurrogateCharEntity(char lowChar, char highChar)
        {
            _wrappedXmlWriter.WriteSurrogateCharEntity(lowChar, highChar);
            _buffer.WriteSurrogateCharEntity(lowChar, highChar);
        }

and so on...

Implement the interface XmlWriter with the same structure as the example overrides. I also made an event-args class to transport the SOAP message out.

public class StringPayloadEventArgs : EventArgs
    {
        public string Payload { get; }

        public StringPayloadEventArgs(string payload)
        {
            Payload = payload;
        }
    }

You can also use the same idea for the incomming SOAP messages.

Rainer
  • 803
  • 10
  • 8