Output Caching Profiles and Custom Caching

Ambrose Little / Friday, August 18, 2006

Here's a quick tip for something pretty neat in ASP.NET 2.0.  You can specify output cache profiles in the application configuration like so (this is under the system.web configuration section):

<caching>
 
<outputCache enableOutputCache="true" />
  <
outputCacheSettings>
   
<outputCacheProfiles>
      <
add name="StandardPages" duration="300" varyByCustom="browser;culture" />
    </
outputCacheProfiles>
  </
outputCacheSettings>
</
caching>

Then in your Global.asax code, add the following handler:

public override sealed string GetVaryByCustomString(HttpContext context, string custom)
{
 
string[] variances = custom.Split(';');
  System.Text.
StringBuilder response = new System.Text.StringBuilder();
  foreach (string variance in variances)
  {
   
switch (variance)
    {
     
case "browser":
        response.Append(
this.Request.Browser.Type);
       
break;
      case "culture":
        response.Append(System.Globalization.CultureInfo.CurrentUICulture.LCID.ToString());
        break;
      }
    }
 
return response.ToString();
}

Now, on any pages you want to be cached like this, you can just add the output cache directive like so:

<%@ OutputCache CacheProfile="StandardPages" %>

Of course, you can add other profiles for pages that, say, vary by parameters, controls, and the like, but this makes it easy to control the caching of all of a kind of a page via the web.config and also shows how you might set up a profile that varies by browser and culture.  And with an implementation of GetVaryByCustom like this, you can add your own variances and mix and match them in your profiles as desired.  It makes for a pretty flexible caching system.  For instance, you could add a check for authentication and, if authenticated, effectively turn off caching by appending a user ID or name and the current date and time (DateTime.Now.ToString()).  That way pages would be cached for anonymous visitors but for authenticated users, where the content is more dynamic, you might not want to cache.