views:

323

answers:

1

I have a simple c# 3.5 .Net console application that hooks up to a service reference. Everything's working fine - making calls and receiving responses, but now I've been told to look at the Soap header in the message that's coming back.

I've found the .Net WebService Studio which is pretty awesome and will show both the Soap request and the Soap response.

For a response, it shows something like this:

ResponseCode: 200 (OK)
Content-Language:en-US
Content-Length:30048
Content-Type:text/xml; charset=utf-8
Date:Mon, 25 Jan 2010 19:57:47 GMT
Server:WebSphere Application Server/6.1

<?xml version="1.0" encoding="utf-16"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
  <soapenv:Header />
  <soapenv:Body>

How can I generate something similar in my application?

The response I'm interested in looking at is for a different method that returns a large enough message to blow up the WebService Studio. I don't see how to set message size parameters using this tool. So, I want to just capture this information myself.

Any ideas on how I can do this?

+2  A: 

WCF has tracing via the config file, or you can implement a behavior to log the message yourself.

Add the behavior like this:

Service1SoapClient client = new Service1SoapClient();
client.Endpoint.Behaviors.Add( new MessageInspectionBehavior());
client.HelloWorld();

and the code:

class MessageInspectionBehavior : IClientMessageInspector, IEndpointBehavior
{
    public void Validate(ServiceEndpoint endpoint)
    {
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(this);
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        //Write request message
        Console.WriteLine(request.ToString());
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        // Write out http headers
        foreach (var property in reply.Properties)
        {
            if (!(property.Value is HttpResponseMessageProperty)) continue;
            var httpProperties = (HttpResponseMessageProperty)property.Value;
            foreach (KeyValuePair<object, object> kvp in httpProperties.Headers)
            {
                Console.WriteLine(kvp.Key + ":" + kvp.Value);
            }
        }
        // Write result message
        Console.WriteLine(reply.ToString());
    }
}

Similarly you can write a logger on a service side with IDispatchMessageInspector and IServiceBehavior.

Mikael Svenson
Nifty! I'm gonna give that a whirl tomorrow! :) Thanks!
Terry Donaghe
Added an edit to display the http headers of the response as well.
Mikael Svenson