Search code examples
c#wcf

How to obtain header values from Client Message Inspector in WCF


I'm creating a web test client for some services I'm working on, and as part of the requirements for that, I would like to be able to display the full request and response SOAP messages (and HTTP headers to the user).

I implemented a MessageInspector class implementing IClientMessageInspector, most notably the BeforeSendRequest and AfterReceiveReply methods to get access to the request & response messages respectively.

Capturing the response (AfterReceiveReply) works great, but capturing the request only partially works. I can access most of the message, however the SOAP header and HTTP headers are both empty. Viewing the request in Fiddler, I can see that WCF is sending a Security header in the SOAP message and "a bunch" of HTTP headers.

My BeforeSendRequest method is very simple...the gist of it is...

public object BeforeSendRequest(ref Message request, IClientChannel channel)
{  
    this.RequestMessage = request.ToString(); // Security header is missing from message

    // Try to get HTTP headers
    object req; // req is always null
    if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out req))
    {
        this.RequestHeaders = ((HttpRequestMessageProperty)req).Headers;
    }

    return null;
}

I'm not sure why the HTTP and Security headers are missing. Is there a better way to do this?

  • Wayne

Solution

  • The inspectors look at the messages right after the message exists the formatter, and before it reaches any of the protocol channels (such as security) which will (potentially) change the message before passing it over (see the diagram in the post about WCF channels at https://learn.microsoft.com/en-us/archive/blogs/carlosfigueira/wcf-extensibility-channels). So at the inspector level you won't be able to find any additional SOAP headers added by the message. The HTTP headers are added by the transport which is also reached after the message passes through the message inspector.

    If you want to see all the SOAP headers in the message, you can either create a new "protocol" channel (the sample at http://msdn.microsoft.com/en-us/library/ms751495.aspx does exactly that) or a new message encoder (it can wrap the existing encoder, and inspect the outgoing messages right before they're encoded).

    To be able to see the HTTP headers it's harder, since the transport is the last part through which the message passes in WCF. I think you could write a custom transport channel to do that, but that would definitely be a lot of code.