If you would like to hire my services, you can now do so by visiting the following link:
Website Design Darlington
Article Statistics
Code Bank Statistics
Summary: You can use Response.Filter to get a reference to the final HTML that will be sent to the client
Sometimes, we need to see the actual HTML that is going to be sent to our client once a page is requested. There are many uses for this and to demonstrate it's functionality, I'm going to show you how the Response.Filter class can be used to intercept the HTML and change some text before it is sent to the client.First, let's create a page named "MyPage.aspx" and add the following: <%@ Page Language="VB" AutoEventWireup="false" CodeFile="MyPage.aspx.vb" Inherits="MyPage" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> Hello World! </div> </form> </body> </html> If we run this page, we see our simple page displayed and the "Hello World!" message is displayed.To intercept and get a reference to the HTML, we now need to create a class to inherit System.IO.Stream. So, create a new class in your App_Code folder, call it "ReplaceHTML" and add the following code: Imports Microsoft.VisualBasic Public Class ReplaceHTML Inherits System.IO.Stream Private Base As System.IO.Stream Public Sub New(ByVal ResponseStream As System.IO.Stream) If ResponseStream Is Nothing Then Throw New ArgumentNullException("ResponseStream") Me.Base = ResponseStream End Sub Public Overrides ReadOnly Property CanRead() As Boolean Get End Get End Property Public Overrides ReadOnly Property CanSeek() As Boolean Get End Get End Property Public Overrides ReadOnly Property CanWrite() As Boolean Get End Get End Property Public Overrides Sub Flush() End Sub Public Overrides ReadOnly Property Length() As Long Get End Get End Property Public Overrides Property Position() As Long Get End Get Set(ByVal value As Long) End Set End Property Public Overrides Function Read(ByVal buffer() As Byte, ByVal offset As Integer, ByVal count As Integer) As Integer Return Me.Base.Read(buffer, offset, count) End Function Public Overrides Function Seek(ByVal offset As Long, ByVal origin As System.IO.SeekOrigin) As Long End Function Public Overrides Sub SetLength(ByVal value As Long) End Sub Public Overrides Sub Write(ByVal buffer() As Byte, ByVal offset As Integer, ByVal count As Integer) ' Get HTML code Dim HTML As String = System.Text.Encoding.UTF8.GetString(buffer, offset, count) ' Replace the text with something else HTML = HTML.Replace("Hello World!", "I've replaced the Hello World example!") ' Send output buffer = System.Text.Encoding.UTF8.GetBytes(HTML) Me.Base.Write(buffer, 0, buffer.Length) End Sub End Class You can see from the above code that when the class is created, the New method sets it's "Base" variable to the ResponseStream that we will soon send in from the page. The Write method then performs a Replace on the actual HTML and then we write it back out.All we need to do now is tell the page to call this class when the page loads. This is where the Response.Filter method comes in and it's very easy to implement. Simply add this code to the "MyPage.aspx" page that we created earlier: Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Response.Filter = New ReplaceHTML(Response.Filter) End Sub Now, when we run the page, our "Hello World!" text has been replaced just as we asked it to!Obviously this is just a simple example, but this could easily be extended to incorporate Regular Expressions if anything more complicated is needed, but hopefully this provides a starting point.
Posted on 13/03/2007 05:52:34
1. Hai 31/03/2007 06:40:16
This is cool! I think one of the application of this could be for a search result page, where we want to intercept final output to hight light the matching texts. I am working on this capability for application and was thinking I might have to use HTTPHandler module. But this approach might be easier....-- Hai
2. Chris Davis 31/03/2007 09:35:22
Yeah, I really like it, is there any benefit doing it here, instead of wroting a http module?
3. PohEe.com 31/03/2007 10:57:35
Me too. I also wanna know the benefit of implementing this Response.Filter.
4. Mark Smith 01/04/2007 01:53:01
Hi,Thanks for your comments. I don't think there is a great advantage if you used this method instead of using a Http Module, however as I understand it, the processing order may have some influence on which method you choose to use. Response Filters are supposed to be applied after all the Http Modules have been processed which means you could even use this method in conjunction with a module yet still retain the ability to perform any additional logic you need.Thanks,Mark
5. DotNetUrls.com 01/04/2007 18:22:15
This simplest way is to override the Render method of the Page class and perform the replace within this method, see the sample code below:<%@Page Language="C#" debug="true"%><%@ Import NameSpace="System.IO"%><script language="C#" runat="server">protected override void Render(HtmlTextWriter writer){TextWriter output=new StringWriter();base.Render(new HtmlTextWriter(output));writer.Write(output.ToString().Replace("Hello,World!","This is the replaced text! Welcome to <a href=\"http://www.dotneturls.com\">www.dotneturls.com</a>"));}</script><HTML><HEAD><TITLE>Http filter test</TITLE></HEAD><BODY>Hello,World!</BODY></HTML>If you want to intercept output html of more than one page, you could write a base class that inherited from the System.Web.UI.Page class and put the above code into it, then inherits other pages from this base Page class and you're done.
6. Jasmine 24/05/2007 12:24:39
Cool! I have a client that, for compliance purposes, wants me to replace some text, but only when certain customers are logged in. This is a great way to do it! Thanks, I was afraid it was going to be complicated :)
7. Andrey Tagaew 23/10/2007 01:36:26
The above example with overriding render is not always working. I used this way for a long term of time but in some cases base.Render(new HtmlTextWriter.....) does not render anything when calling base.Render(writer) renders the content fine. I think its because we are trying to use TextWriter or StringWriter when ASP.NET is using HttpWriter that is slightly different. Unfortunately we can't create instance of HttpWriter, thus have to use other inherited from TextWriter classes.The way of using Filter works fine for me in all cases. So, thanks a lot!
8. Ted 18/01/2008 04:16:20
Another potential risk is that the Filter (which processes one certain buffered string at a time) "clips" in the middle of the string you want to replace. For example, say the first buffer contains "Hello World!", "I've replaced" and the next buffer contains the remaining part of the string. In this case we wouldn't be able to locate and replace the full string. This is particularly hazardous when the HTML source code contains line breaks.
Please keep your comments relevant to this page. Any inappropriate or purely promotional comments may be removed. Email addresses are never displayed but are required so you can confirm your comments.