Logging for C# Webservices -
we consuming web services. use wsdl.exe generate client proxy.
how keep underlying xml files proxy sends , receives web services provider?
the purpose protect ourselves showing did have send parameters in format when system malfunctions , disputes arise.
we did using soapextension in application making web service requests.
the entire system consisted of 2 classes, copystream
class provided ability duplicate contents of stream second stream read / written to, , soaplogger
class intercepts soap requests , responses in application , logs them file.
you need register in app.config file:
<configuration> <system.web> <webservices> <soapextensiontypes> <add type="mynamespace.soaplogger, myassembly" priority="3" group="high" /> </soapextensiontypes> </webservices> </system.web> </configuration>
apologies big blob of code, here is:
/// <summary> /// extension allow logging of soap request , response xml. /// </summary> public class soaplogger : soapextension { private memorystream copystream; public override stream chainstream(stream stream) { this.copystream = new memorystream(); return new copystream(stream, copystream); } public override object getinitializer(type servicetype) { return null; } public override object getinitializer(logicalmethodinfo methodinfo, soapextensionattribute attribute) { return null; } public override void initialize(object initializer) { } public override void processmessage(soapmessage message) { switch (message.stage) { case soapmessagestage.afterserialize: case soapmessagestage.afterdeserialize: log(message); break; } } private void log(soapmessage message) { string messagetype; if (message.stage == soapmessagestage.afterdeserialize) { messagetype = message soapservermessage ? "soaprequest" : "soapresponse"; } else { messagetype = message soapservermessage ? "soapresponse" : "soaprequest"; } streamreader reader = new streamreader(new memorystream(this.copystream.toarray())); logger.log(string.format( "{0} ({1}):\r\n{2}", messagetype, message.methodinfo.name, reader.readtoend() )); } } /// <summary> /// implementation of stream wraps existing stream while copying written /// or read stream. /// </summary> public class copystream : stream { public stream basestream { { return this.basestream; } } private stream basestream; public stream otherstream { { return this.otherstream; } } private stream otherstream; public copystream(stream basestream, stream otherstream) { if (basestream == null) { throw new argumentnullexception("basestream"); } if (otherstream == null) { throw new argumentnullexception("otherstream"); } this.basestream = basestream; this.otherstream = otherstream; } public override bool canread { { return this.basestream.canread; } } public override bool canseek { { return this.basestream.canseek; } } public override bool canwrite { { return this.basestream.canwrite; } } public override void flush() { this.basestream.flush(); } public override long length { { return this.basestream.length; } } public override long position { { return this.basestream.position; } set { this.basestream.position = value; } } public override int read(byte[] buffer, int offset, int count) { int returnvalue = basestream.read(buffer, offset, count); this.otherstream.write(buffer, offset, returnvalue); return returnvalue; } public override long seek(long offset, seekorigin origin) { try { this.otherstream.seek(offset, origin); } catch { } return basestream.seek(offset, origin); } public override void setlength(long value) { try { this.otherstream.setlength(value); } catch { } this.basestream.setlength(value); } public override void write(byte[] buffer, int offset, int count) { try { this.otherstream.write(buffer, offset, count); } catch { } this.basestream.write(buffer, offset, count); } }
its not been performance / stress tested, seems holding fine - hopefully way stream copying done should mitigate performance impact.
Comments
Post a Comment