Click here to Skip to main content
13,089,943 members (44,411 online)
Click here to Skip to main content
Add your own
alternative version


22 bookmarked
Posted 15 May 2008

Problem with Response.Write - Changing Dynamic Content Without Corruption

, 15 May 2008
Rate this:
Please Sign up or sign in to vote.
Changing HTML content of an ASP.NET page using a new technique that handles Response.Write().


When you need to dynamically control the HTML that is generated from your ASP.NET page or control, a popular technique to do that is to override the render function: protected override void Render(HtmlTextWriter writer). It is a function where you can get great power over your control. The function simply sends an HtmlTextWriter, which is a stream where you can write anything and it will appear on the client screen, as we can see in the code below.

protected override void Render(HtmlTextWriter writer)

The Problem

Now, let us change the page data instead of replacing it. The attached sample contains two ASPX pages, both with the same HTML structure as follows:

<table> <tr> <td>
        Hello ( <%Response.Write(@"Mr. XYZ"); %> $MSG$       
</td> </tr> </table>

All we need to do is replace $MSG$ with a message "How R U?" by capturing the rendering event. The required result should be as in the following figure:


Let us write the code:

protected override void Render(HtmlTextWriter writer) 
    // Create your HTMLTestWriter
   System.Text.StringBuilder oPageContents = new System.Text.StringBuilder();
    System.IO.StringWriter oSW = new System.IO.StringWriter(oPageContents);
    System.Web.UI.HtmlTextWriter oHtmlWriter = new System.Web.UI.HtmlTextWriter(oSW);
    // Give the page a fake streamer to capture HTML contents.
    oPageContents = oPageContents.Replace("$MSG$", "How R U ?");
    // Write data back into the original stream
    System.IO.StringReader oSR = new System.IO.StringReader(oPageContents.ToString ());
    writer.Write(oSR.ReadToEnd ()); 

Nothing strange about this code, and it can be found all over the internet. The idea behind it is that you replace the given HtmlTextWriter that you can only write into, with another one that streams data into a StringBuilder object, oPageContents. Once the HTML is in the oPageContents StringBuilder, you can read and modify it easily. The next step is to write your contents in the actual HtmlTextWriter that is passed as a parameter in the Render function. It is pretty straightforward :) Wait, the result is not what you want??!!

The strange thing is that you don't get the desired result; instead, you get the following result:


I spent a couple of days searching why this happened. And finally, I found the answer. Response.Write() does not send its contents through base.Render that is used to render the control. Response.Write(), in fact, the HtmlTextWriter stream sends the data eventually to the Response object.


So what happens here is that while base.Render() is working, when Response.Write() takes place, it sends data directly out, while the other data are all stored in our local StringBuilder, and then we inject them in to the writer, but then it is too late, as the order of streaming output now has been corrupted.

Solution - HTML Streamer

HTMLStreamer solves this issue by acting as a double streamer. It streams data to a StringBuilder object as in our previous sample. At the same time, it streams data to a writer parameter of type HtmlTextWriter. The data is submitted synchronized to the Response object, while another copy is saved in the StringBuilder object.

public class HTMLStreamer: System.IO.StringWriter 
    protected System.Web.UI.HtmlTextWriter mHtmlTextWriter;
    public HTMLStreamer(System.Text.StringBuilder oStringBuilder, 
                        System.Web.UI.HtmlTextWriter innerWriter) 
        : base(oStringBuilder)
        mHtmlTextWriter = innerWriter;
    public override void Write(string value) 
        // Change content dynamically here.
        if (value.IndexOf("$MSG$")!=-1) 
            value = value.Replace("$MSG$","How R U ?"); 
        mHtmlTextWriter.Write(value); base.Write(value); 
    public override void Write(char[] buffer, int index, int count)
        mHtmlTextWriter.Write(buffer, index, count);
        base.Write(buffer, index, count);

    public override void Write(char value) 

Now back to the Render() function; it should be handled as follows:

protected override void Render(HtmlTextWriter writer) 
    // Create your string builder.
    System.Text.StringBuilder oPageContents = new System.Text.StringBuilder();
    // Create HTMLStreamer and put both writer & oPageContents into it.
    HTMLStreamer oSW = new HTMLStreamer(oPageContents, writer); 
    // Create HTMLTextWriter that contains the double-stream class "HTMLStreamer"
    System.Web.UI.HtmlTextWriter oHtmlWriter = new System.Web.UI.HtmlTextWriter(oSW);
    // Get HTML contents.


A delegate is called in all Write() functions of HTMLStreamer so that it can be used by the page to change the contents without the need to write into the HTMLStreamer itself and so it can be used as a separate DLL. If you have any idea on how to capture Response.Write(), please let me know.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Mohammad Said Hefny
Egypt Egypt
No Biography provided

You may also be interested in...

Comments and Discussions

Suggestion" If you have any idea on how to capture Response.Write() ... " Pin
Micke2nd14-Mar-12 4:42
memberMicke2nd14-Mar-12 4:42 
GeneralExcellent work! Pin
feguardia27-Oct-09 9:59
memberfeguardia27-Oct-09 9:59 
AnswerSimple fix: Use &lt;%= %&gt; instead of &lt;%Response.Write%&gt; Pin
Rick L9-Oct-08 5:19
memberRick L9-Oct-08 5:19 
GeneralGood work !!! Pin
dnpro21-May-08 22:16
memberdnpro21-May-08 22:16 
GeneralAlternative Pin
Matthew Fergusson20-May-08 0:16
memberMatthew Fergusson20-May-08 0:16 
GeneralRe: Alternative Pin
Mohammad Hefny10-Aug-08 2:26
memberMohammad Hefny10-Aug-08 2:26 
GeneralRe: Alternative Pin
J. Moreno22-Jun-09 8:02
memberJ. Moreno22-Jun-09 8:02 
AnswerRe: Alternative Pin
Micke2nd14-Mar-12 4:31
memberMicke2nd14-Mar-12 4:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170813.1 | Last Updated 15 May 2008
Article Copyright 2008 by Mohammad Said Hefny
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid