Capturing SOAP requests to an ASP.NET ASMX web service

You can also implement by placing the code in Global.asax.cs

protected void Application_BeginRequest(object sender, EventArgs e)
{
    // Create byte array to hold request bytes
    byte[] inputStream = new byte[HttpContext.Current.Request.ContentLength];

    // Read entire request inputstream
    HttpContext.Current.Request.InputStream.Read(inputStream, 0, inputStream.Length);

    //Set stream back to beginning
    HttpContext.Current.Request.InputStream.Position = 0;

    //Get  XML request
    string requestString = ASCIIEncoding.ASCII.GetString(inputStream);

}

I have a Utility method in my web service that I use to capture the request when something happens that I am not expecting like a unhandled exception.

    /// <summary>
    /// Captures raw XML request and writes to FailedSubmission folder.
    /// </summary>
    internal static void CaptureRequest()
    {
        const string procName = "CaptureRequest";

        try
        {
            log.WarnFormat("{0} - Writing XML request to FailedSubmission folder", procName);

            byte[] inputStream = new byte[HttpContext.Current.Request.ContentLength];

            //Get current stream position so we can set it back to that after logging
            Int64 currentStreamPosition = HttpContext.Current.Request.InputStream.Position;

            HttpContext.Current.Request.InputStream.Position = 0;

            HttpContext.Current.Request.InputStream.Read(inputStream, 0, HttpContext.Current.Request.ContentLength);

            //Set back stream position to original position
            HttpContext.Current.Request.InputStream.Position = currentStreamPosition;

            string xml = ASCIIEncoding.ASCII.GetString(inputStream);

            string fileName = Guid.NewGuid().ToString() + ".xml";

            log.WarnFormat("{0} - Request being written to filename: {1}", procName, fileName);

            File.WriteAllText(Configuration.FailedSubmissionsFolder + fileName, xml);
        }
        catch
        {
        }

    }

Then in web.config I store several AppSetting values that define what level I want to use to capture the request.

    <!-- true/false - If true will write to an XML file the raw request when any Unhandled exception occurrs -->
    <add key="CaptureRequestOnUnhandledException" value="true"/>

    <!-- true/false - If true will write to an XML file the raw request when any type of error is returned to the client-->
    <add key="CaptureRequestOnAllFailures" value="false"/>

    <!-- true/false - If true will write to an XML file the raw request for every request to the web service -->
    <add key="CaptureAllRequests" value="false"/>

Then in my Application_BeginRequest I have it modified like so. Note that Configuration is a static class I create to read properties from web.config and other areas.

    protected void Application_BeginRequest(object sender, EventArgs e)
    {

        if(Configuration.CaptureAllRequests)
        {
            Utility.CaptureRequest();
        }
    }

Leave a Comment