How to retrieve the HTML response generated by ASP.NET pages using HTTP module

Many developers come up with this question: How to retrieve the HTML response generated by ASP.NET pages?

We can implement this by writing a HTTP module. We need to create a custom Stream object and set the Filter property of the Response object to this Stream object so that all HTTP output sent by Write passes through the filter.

I am writing a sample code here. Tune it according to your requirement:

using System;

using System.IO;

namespace MySamples

{

public class ResponseCapture : System.Web.IHttpModule

{

private System.Web.HttpApplication app;

public ResponseCapture()

{

}

public void Init(System.Web.HttpApplication application)

{

application.BeginRequest += new System.EventHandler(BeginRequest);

app = application;

}

public void BeginRequest(Object sender, EventArgs e)

{

ResponseStream mStreamFilter = new ResponseStream(app.Response.Filter);

app.Response.Filter = mStreamFilter;

}

public class ResponseStream : System.IO.Stream

{

private System.IO.Stream objStream;

private long lngLength;

private long lngPosition;

private System.IO.StreamWriter objStreamWriter;

public ResponseStream(System.IO.Stream stream)

{

objStream = stream;

objStreamWriter = new System.IO.StreamWriter(objStream);

}

public override bool CanRead

{

get

{

return false;

}

}

public override bool CanSeek

{

get

{

return true;

}

}

public override bool CanWrite

{

get

{

return true;

}

}

public override long Length

{

get

{

return lngLength;

}

}

public override long Position

{

get

{

return lngPosition;

}

set

{

lngPosition = value;

}

}

public override int Read(Byte[] buffer, int offset, int count)

{

throw new NotSupportedException();

}

public override long Seek(long offset, System.IO.SeekOrigin direction)

{

return objStream.Seek(offset, direction);

}

public override void SetLength(long length)

{

lngLength = length;

}

public override void Close()

{

objStream.Close();

}

public override void Flush()

{

objStream.Flush();

}

public override void Write(byte[] buffer, int offset, int count)

{

System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding();

System.Text.StringBuilder strBuffer = new System.Text.StringBuilder(utf8.GetString(buffer));

// Output is now stored in the strBuffer object. Use it the way you want. I am writing to a text file in this sample.

WriteToFile(strBuffer);

objStreamWriter.Write(strBuffer.ToString());

}

public void WriteToFile(System.Text.StringBuilder strBuffer)

{

StreamWriter sw = new StreamWriter("c:\\inetpub\\wwwroot\\html.txt");

sw.Write(strBuffer.ToString().Trim());

sw.Close();

}

}

public void Dispose()

{

}

}

}

Deployment steps:

=================

1. Compile the above class to a dll copy it to the target ASP.NET application’s bin directory.

2. Add the following entry within the <system.web> tag in the web.config file of the target ASP.NET application.

<httpModules>

<add name="ResponseCap" type="MySamples.ResponseCapture,ResponseCapture" />

</httpModules>

When you access a page from the asp.net application, the html.txt file will be created in the "C:\inetpub\wwwroot" location. (This location is just for testing. You can change as you want in the source code)

Comments

  • Anonymous
    May 13, 2009
    Hi Pradeep, Thats a great post... I have created a Custom HTTP Module similar to yours. It works fine in a normal site but the problem arises with the Ajax enabled web site. Here also my Module is doing it job well but the problem is with the ajax controls. It gives me an error sys is undefined. I think this is due to to module that is added by default for ajax enabled web site <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> Please Help..