While this solution might seems a little odd (or more correctly the problem might seem very odd) but this technique has sure solved a lot of problems for me.
What I'm gonna show you is a was to manipulate the resulting HTML and ASP.NET page has generated just before it's sent to the browser.
Now you might ask, isn't that what ASP Server controls are made for? To generate the HTML for you? Because there are certain times when the HTML or JavaScript it generates are not right and you might even not (if using a third party control) be able to modify the underlying control generating the code.
For example I've had problems with some thirdparty components where I was unable to get it to render the correct paths for including images etc (it simply couldn't point to the specific location I had them stored).
So, the plan is to somehow intercept the rendering, make my modifications to the HTML generated and then just pass my modified copy on to the browser.
One other example (which I actually have used in some projects) is to create some sort of "template replacer", where others can create their own templates and also write some special tags that your application is supposed to replace with some meaningful - for example
$currentarticle_name might be replaced with
the name of the current article (the one the user is browsing)
Thats the type of example I am gonna show you, consider this layout:

Now, we are supposed to replace the $CURRENT_DATETIME text with current date and time.
I.e we want this result when running:

So first the code - all the magic happens in Render:
protected override void Render(HtmlTextWriter writer)
{
using(System.IO.MemoryStream msOur = new System.IO.MemoryStream())
{
using(System.IO.StreamWriter swOur = new System.IO.StreamWriter(msOur))
{
HtmlTextWriter ourWriter = new HtmlTextWriter(swOur);
base.Render(ourWriter);
ourWriter.Flush();
msOur.Position = 0;
using(System.IO.StreamReader oReader = new System.IO.StreamReader(msOur))
{
string sTxt = oReader.ReadToEnd();
sTxt = sTxt.Replace("$CURRENT_DATETIME", DateTime.Now.ToString());
Response.Write(sTxt);
oReader.Close();
}
}
}
}