I'd like to use caching in my application but the data I'm returning is specific to the logged in user. I can't use any of the out of the box caching rules when I need to vary by user.
Can someone point me in the right direction on creating a custom caching attribute. From the controller I can access the user from Thread.CurrentPrincipal.Identity;
or a private controller member that I initialize in the controller constructor _user
Thank you.
You could use the VaryByCustom. In Global.asax override the GetVaryByCustomString
method:
public override string GetVaryByCustomString(HttpContext context, string arg)
{
if (arg == "IsLoggedIn")
{
if (context.Request.Cookies["anon"] != null)
{
if (context.Request.Cookies["anon"].Value == "false")
{
return "auth";
}
else
{
return "anon";
}
}
else
{
return "anon";
}
}
else
{
return base.GetVaryByCustomString(context, arg);
}
}
and then use the OutputCache attribute:
[OutputCache(CacheProfile = "MyProfile")]
public ActionResult Index()
{
return View();
}
and in web.config:
<caching>
<outputcachesettings>
<outputcacheprofiles>
<clear />
<add varybycustom="IsLoggedIn" varybyparam="*" duration="86400" name="MyProfile" />
</outputcacheprofiles>
</outputcachesettings>
</caching>
The Authorize Attribute has some interesting things going on regarding caching for authorized vs unauthorized users. You may be able to extract it's logic and modify it to cache per authorized user, instead of just per-"the user is authorized".
Check out this post:
Can someone explain this block of ASP.NET MVC code to me, please?
You should use OutputCache.VaryByCustom Property to specify custom vary string. And to use it, you should override method in your Global.asax
public override string GetVaryByCustomString(HttpContext context, string arg)
{
if(arg.ToLower() == "currentuser")
{
//return UserName;
}
return base.GetVaryByCustomString(context, arg);
}