Saving Rendered ASP.NET controls to files

This is a pattern I use frequently -- for example, if I have rendered some RSS format search results to a page, I may want to save this generated HTML of the DataList (or a Gridview, or any other UI display control) to a file, which can easily be read back in later and assigned to an HtmlGeneric Control that is then attached to a placeholder on an ASPX page, kind of like a FileSystem Caching mechanism:

this.DataList1.DataBind();
System.IO.StringWriter oStringWriter = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);
DataList1.RenderControl(oHtmlTextWriter);
StreamWriter sr = null;
string fullFilePath = Server.MapPath("mySavedDataList1.htm");
try
{
sr = new StreamWriter(fullFilePath);
string oStuff = oStringWriter.ToString();
sr.Write(oStuff)
}
catch (Exception ex)
{
// Exception Handler here
finally
{
if (sr != null)
{
sr.Close();
sr.Dispose();
}
}


What this does is wrap an HtmlTextWriter around a StringWriter, then call the RenderControl method of the control whose contents we want to save, into the HtmlTextWriter. We then create a StreamWriter into our file path, call the ToString() method on the StringWriter to get out our content, and using the StreamWriter, we write the content to the file.

Later on, if there is a request for this specific content, instead of having to go to our database or make our WebClient search all over again, we can simply look to see if we have cached the content on the filesystem. If so, we only need to load it and display it.

Comments

  1. Anonymous3:00 AM

    I like this! I've been considering doing this for some of my most used controls. So loading this from file would be faster than going to the Database to get it?

    How would you suggest a person controls when to re-render the file? Seems it might be expensive to load the file and see it's last modified date? I'm interested in if A) this will load faster and B) how to efficiently reload and rewrite the "cached" file based on its age.

    ReplyDelete
  2. You can reload the file with a FileStream:

    FileStream fs = new FileStream(Server.MapPath(myfilePathStringVariable));
    You can use File.Exists to test whether you need to "go get" the file instead (and save the contents).
    Rewriting normally would be done by attaching the string to the InnerHtml property of a div with runat=server. Its faster depending on how long it takes to get the original.

    ReplyDelete
  3. Anonymous9:00 AM

    Hey, this is a *very* interesting approach! Thanks for sharing!

    ReplyDelete
  4. If the purpose is just for caching, how is this not covered by the partial page/control caching already natively supported by asp.net?

    ReplyDelete
  5. The purpose is not just "Caching" - at least, not in memory. It's to save the rendered HTML content on the filesystem. There are all kinds of ways to "cache" output, including ones like partial page or substitution caching, but none of them persist the content permanently until you decide you want to delete it.

    ReplyDelete
  6. Anonymous2:42 AM

    I've seen some unexpected performance drops by using the file system over a SQL Server backend. Particulary using SQLite is (at least on my host) waaay slower than using SQL Server, maybe it's SQLite issue and not a fil system vs SQL Server, but thats my experience anyway.

    ReplyDelete

Post a Comment

Popular posts from this blog

Some observations on Script Callbacks, "AJAX", "ATLAS" "AHAB" and where it's all going.

IE7 - Vista: "Internet Explorer has stopped Working"

FIREFOX / IE Word-Wrap, Word-Break, TABLES FIX

System.Web.Caching.Cache, HttpRuntime.Cache, and IIS Recycles

FIX: Requested Registry Access is not allowed (Visual Studio 2008)