28 February 2011

ASP.NET 2.0 - Post Cache Substitution

Fragment Caching - where you cache a user control, so the entire page isn't cached, but the small portion of the page you wanted to be cached, is cached.
Well, Post-Cache Substitution is the exact opposite of that - the entire page is cached, except that little teenie weenie that you want to keep dynamic. It is implemented as the HttpResponse.WriteSubstitution method.
public void WriteSubstitution (HttpResponseSubstitutionCallback callback)
Per MSDN - "HttpResponse.WriteSubstitution allows insertion of response substitution blocks into the response, which allows dynamic generation of specified response regions for output cached responses",
... which in english means, when the ASP.NET page renders, your method which you passed in as the HttpResponseSubstitutionCallback delegate is called (callback?) to get the dynamic content, which is then inserted into the cached content and voilla - you got Post-Cache substitution. Cool eh? :)
Now here's the catch - the method that will sit inside HttpResponseSubstitutionCallback delegate instance, has to be either static or global or basically "instantiated and ready to eat". Why? Because ASP.NET will need to be able to call it without actually instantiating the page (i.e. when fetching from cache). The signature of HttpResponseSubstitutionCallback is quite straightforward -
public delegate string HttpResponseSubstitutionCallback (HttpContext context)
So a sample function could be -
public static string GetMyContent(HttpContext context)
   return " This blog rocks " ;
And how you'd hook it up inside your page is like this -
protected voide Page_Load(object sender, EventArgs e)
   Response.WriteSubstitution(new HttpResponseSubstitutionCallback(GetMyContent)) ;
But wait a minute - we're talking with the "Response" object - whatever happened to the fancy ASP.NET object model that we should have been using? Yeah I know it sucks, but for Post-Cache substitution, you hafta work with the Response object and not the object model. One explanation of this implementation could be - You don't really have the object model without instantiation the page (i.e. when fetching it out of the cache) - heh :) that makes sense.
But you could always wrap the substitutable content inside your own control, or heck ASP.NET 2.0 even comes with a generic substitution control that looks like this -
WOOHOO !! :) - now that's more elegant and now you don't need that programmatic Page_Load hookup either.