14

Perhaps I'm going about this all wrong (and please tell me if I am), but I'm hitting my head against a wall with something that seems like a really simple concept.

This Render override is coming from a User Control.

protected override void Render(HtmlTextWriter writer)
{
    string htmlAboutToBeRendered = writer.GetWhatHasBeenWrittenToTheWriterSoFar();

    // Do something nefarious, yet unrelated with htmlAboutToBeRendered
}

This seems like a there would be an obvious way to do this, but I can't seem to find it.

Can anyone shed some light on this for me, please?

Adam McKee
  • 802
  • 2
  • 8
  • 14

3 Answers3

24

Try this:

protected override void RenderContents(HtmlTextWriter output)  
{  
   StringBuilder sb = new StringBuilder();  
   HtmlTextWriter htw = new HtmlTextWriter(new System.IO.StringWriter(sb,   
   System.Globalization.CultureInfo.InvariantCulture));  
   foreach (Control ctrl in Controls)  
   {  
      ctrl.RenderControl(htw);  
   }  
  string strContents = sb.ToString();  

}

TheTXI
  • 37,429
  • 10
  • 86
  • 110
  • 1
    Just to follow up - I popped open Reflector and found that the Render method just recusively calls RenderChildren for each control in the tree under the User Control. This means you were spot-on about this. Thanks again! – Adam McKee Jun 17 '09 at 20:39
3

You can derive from HttpTextWriter and override OnTagRender, OnAttributeRender and OnStyleRender methods and modify the tags as they are rendered. The MSDN docs for OnTagRender show a sample where the tag is modified during rendering:

http://msdn.microsoft.com/en-us/library/system.web.ui.htmltextwriter.ontagrender.aspx

Robert Horvick
  • 3,966
  • 21
  • 18
1

Alternate method using relfection:

private string GetString(HtmlTextWriter writer) 
{
   // the flags to see the internal properties of the writer
   System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.Default;
   flags |= System.Reflection.BindingFlags.NonPublic;
   flags |= System.Reflection.BindingFlags.Instance;
   flags |= System.Reflection.BindingFlags.FlattenHierarchy;
   flags |= System.Reflection.BindingFlags.Public;

   // get the information about the internal TextWriter object
   System.Reflection.FieldInfo baseWriter = writer.GetType().GetField("writer", flags);

   // use that info to create a StringWriter
   System.IO.StringWriter reflectedWriter = (System.IO.StringWriter)baseWriter.GetValue(writer);

   // now we get a StringBuilder!
   StringBuilder builder = reflectedWriter.GetStringBuilder();

   return builder.ToString();
}

Then it's a simple matter of re-creating the HtmlTextWriter using the string and a StringBuilder.

This was built using a couple clues I picked up from a conversation between Tom Spink and Rotsey on EggheadCafe

Mark
  • 1,449
  • 1
  • 13
  • 13