I'm trying to trouble shoot a web service client in my current project. I'm not sure of the platform of the Service Server (Most likely LAMP). I believe there is a fault on their side of the fence as i have eliminated the potential issues with my client. The client is a standard ASMX type web reference proxy auto generated from the service WSDL.
What I need to get to is the RAW SOAP Messages (Request and Responses)
What is the best way to go about this?
It looks like Tim Carter's solution doesn't work if the call to the web reference throws an exception. I've been trying to get at the raw web resonse so I can examine it (in code) in the error handler once the exception is thrown. However, I'm finding that the response log written by Tim's method is blank when the call throws an exception. I don't completely understand the code, but it appears that Tim's method cuts into the process after the point where .Net has already invalidated and discarded the web response.
I'm working with a client that's developing a web service manually with low level coding. At this point, they are adding their own internal process error messages as HTML formatted messages into the response BEFORE the SOAP formatted response. Of course, the automagic .Net web reference blows up on this. If I could get at the raw HTTP response after an exception is thrown, I could look for and parse any SOAP response within the mixed returning HTTP response and know that they received my data OK or not.
Later ...
Here's a solution that does work, even after an execption (note that I'm only after the response - could get the request too):
Here's how you configure it in the config file:
"TestCallWebService" shoud be replaced with the name of the library (that happened to be the name of the test console app I was working in).
You really shouldn't have to go to ChainStream; you should be able to do it more simply from ProcessMessage as:
If you look up SoapMessage.Stream, it's supposed to be a read-only stream that you can use to inspect the data at this point. This is a screw-up 'cause if you do read the stream, subsequent processing bombs with no data found errors (stream was at end) and you can't reset the position to the beginning.
Interestingly, if you do both methods, the ChainStream and the ProcessMessage ways, the ProcessMessage method will work because you changed the stream type from ConnectStream to MemoryStream in ChainStream, and MemoryStream does allow seek operations. (I tried casting the ConnectStream to MemoryStream - wasn't allow.)
So ..... Microsoft should either allow seek operations on the ChainStream type or make the SoapMessage.Stream truly a read-only copy as it's supposed to be. (Write your congressman, etc...)
One further point. After creating a way to retreive the raw HTTP response after an exception, I still didn't get the full response (as determined by a HTTP sniffer). This was because when the development web service added the HTML error messages to the beginning of the response, it didn't adjust the Content-Length header, so the Content-Length value was less than the size of the actual response body. All I got was the Content-Length value number of characters - the rest were missing. Obviously, when .Net reads the response stream, it just reads the Content-Length number of characters and doesn't allow for the Content-Length value possibily being wrong. This is as it should be; but if the Content-Length header value is wrong, the only way you'll ever get the entire response body is with a HTTP sniffer (I user HTTP Analyzer from http://www.ieinspector.com).
I would prefer to have the framework do the logging for you by hooking in a logging stream which logs as the framework processes that underlying stream. The following isn't as clean as I would like it, since you can't decide between request and response in the ChainStream method. The following is how I handle it. With thanks to Jon Hanna for the overriding a stream idea