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.