Monday, July 4, 2011

Getting headers from a web service

When we add a web service to a project Visual Studio automatically generates proxy classes for us. This was something very unfortunate for me. It doesn't give me header information. So I can't know any header information sent from the server to the client. I had the idea of attaching machine name (of the web server) in the response, and reading this from the client (which is my asp.net application). This would have been a simple task if the web service was exposed as a script service, and, that service was being called by AJAX call.

The problem at hand

The proxy classes generated derive from the SoapHttpClientProtocol class. The derived (web service) class has a lot of functionality built into it which saves us the headache of communicating with XML web services. But, the web service class doesn't expose any way to obtain the header information.

Solution

Fortunately you can derive the web service class and obtain a reference to the WebResponse object which encapsulates the response of the asmx web method which was executed over the internet. All you have to do is inherit the web service class, override the GetWebResponse method, and, make use of this in code.
Imports WebSvcHeaders.TimeService
Imports System.Net
Public Class TimeSvcProxy
    Inherits SimpleWebService

    Private _WebResponse As WebResponse

    Protected Overrides Function GetWebResponse(ByVal request As System.Net.WebRequest) As System.Net.WebResponse
        _WebResponse = MyBase.GetWebResponse(request)
        Return _WebResponse
    End Function

    Function GetResponseHeader(ByVal HeaderKey As String) As String
        Return _WebResponse.Headers(HeaderKey)
    End Function

End Class

Why is this useful?

You can tag diagnostic information in the response headers and then read that information from the client and log it on the client itself. It can be of major help while trying to analyze performance problem with asp.net websites deployed in a web farm, for e.g. We don't know which server in a web farm might service the web method call. Hence tagging, for e.g., the machines name in the response headers and being able to read that from the client gives me a lead to do investigation on the server which processed the call to the web method.

I suppose you can do something similar with WCF web services too. But I don't know if it can be done exactly on the same lines like I've mentioned in my post.