ASP.NET “VaryByCustom” page output caching

Steve Eichert was interested in how to create a custom caching setup, so here are some notes I took from the Devscovery conference.


We all know that the OutputCache directive allows ASP.NET to cache fully-rendered pages. We can instruct ASP.NET to cache different copies based on form variables like this:
<%@ OutputCache Duration=”60” VaryByParam=”ZipCode” %>


Or we can cache based on HTTP Headers like this:
<%@ OutputCache Duration=”60” VaryByParam=”None” VaryByHeader=”User-Agent” %>


The key to creating a custom cache variance is understanding that ASP.NET uses a simple string comparison to determine if a cached result should be returned instead of processing the page. For example, say we want to cache a certain page by SessionID. We add the OutputCache directive like this:
<%@ OutputCache Duration=”60” VaryByParam=”None” VaryByCustom=”SessionID” %>


Now, in global.asax, we must override the GetVaryByCustomString method, like this:


Public override string GetVaryByCustomString(HttpContext context, string arg)
{
  if(arg.ToLower() == “sessionid”)
  {
    HttpCookie cookie = context.Request.Cookies[“ASP.NET_SessionID”];
    if(cookie != null)
      return cookie.Value;
  }
  return base.GetVaryByCustomString(context, arg);
}

That’s it. Simple, elegant, beautiful.

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

8 Responses to ASP.NET “VaryByCustom” page output caching

  1. Darrell says:

    Brian – good catch. I always put a little something in Session state so I had not noticed. Thanks!

  2. Brian Pedersen says:

    Have you noticed, that in some browsers, or in some combinations of browser/personal firewall, you get a new session id each time you refresh (F5) the browser?

    Apparently, the session is (sometimes) only stored if the session instance is actually used.

    To solve this problem, add the following line to your code-behind of your .aspx file:

    this.Session["junk"] = System.DateTime.Now;

    Actually, you can add anything to any session name. What matters is that you use the session instance of the page.

  3. Francis Shanahan says:

    Doesn’t seem to work. It caches but just for a few mins. then seems to flush the cache and regen the page. My directive is set to duration of 50000 my GetVaryByCustomString simply returns "fred" ALWAYS (I was trying to force it to always cache in an effort to debug). Any ideas? What could be happening?

    See the behaviour here: The middle portion is cached, the time of caching is printed in tiny text at the top of the middle section. This time matches the server time (top RIGHT) when the page is generated and then should be less than that time in the cached version.

    ‘ppreciate the help.

    http://www.francisshanahan.com/default.aspx

  4. Francis Shanahan says:

    Well, I actually want to verify the role of the authenticated user aswell but I figured I’d keep the question simple.

    Thanks, I’ll try this tonight.

  5. Darrell says:

    If you only wanted to vary based on whether someone was logged in (not who was logged in), then yes. That’s all you would have to do.

  6. Francis Shanahan says:

    How would this work with authentication? If I’m doing forms authentication and want to vary by whether or not the user’s logged in etc, do I just check for an Identity and return a string "true", "false"?

  7. Darrell says:

    Steve – my pleasure. I haven’t done any ASP.NET stuff lately even though that is one of the things I know most about.

  8. Steve says:

    Nice! Thanks for posting it!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>