6

Is there a way to use the OutputCache attribute to cache the results of only logged out users and reevaluate for logged in users example:

What I'd Like

[OutputCache(onlycacheanon = true)]
public ActionResult GetPhoto(id){
   var photo = getPhoto(id);
   if(!photo.issecured){
      return photo...
   }
   return getPhotoOnlyIfCurrentUserHasAccess(id);
   //otherwise return default photo so please don't cache me
}
maxfridbe
  • 5,872
  • 10
  • 58
  • 80

2 Answers2

8

You can use the VaryByCustom property in [OutputCache].

Then override HttpApplication.GetVaryByCustomString and check HttpContext.Current.User.IsAuthenticated.

  • Return "NotAuthed" or similar if not authenticated (activating cache)
  • Guid.NewGuid().ToString() to invalidate the cache
jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • 1
    That's the very thing I was missing thank you. I didn't realize null disabled caching. – maxfridbe Mar 28 '12 at 06:08
  • Didn't know it was available. Thank you :) –  Mar 28 '12 at 10:09
  • 5
    `null` **does NOT** disable the cache. I've tried that solution on the sample project and it just caches separately for authenticated and non authenticated users... – Cheburek Apr 25 '12 at 10:57
  • @Cheburek You can return Guid.NewGuid().ToString() instead of null, which would make every request unique. But it would have some performance implications. – Doug Feb 21 '13 at 20:27
4

This is how I implemented the above.

In Global.asax.cs:

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    if (custom == "UserId")
    {
        if (context.Request.IsAuthenticated)
        {
            return context.User.Identity.Name;
        }
        return null;
    }

    return base.GetVaryByCustomString(context, custom);
}

Usage in Output Cache Attribute:

 [OutputCache(Duration = 30, VaryByCustom = "UserId" ...
 public ActionResult MyController()
 {
    ...
gls123
  • 5,467
  • 2
  • 28
  • 28