对于网站,我想仅为未经过身份验证的用户缓存这些页面 - 经过身份验证的用户不会获得缓存内容(因为他们将更新并需要立即查看结果)。
我知道如何使用VaryByCustom改变每个用户的缓存: Link1 Link2
...但我无法弄清楚如何完全关闭经过身份验证的用户的缓存。
怎么办?
修改
如果未经身份验证的用户已经存在该页面的缓存版本,则下面的代码会出现问题。基本上,经过身份验证的用户将获得未经身份验证的事物视图。
但是,此处此链接的解决方案有效:Link
答案 0 :(得分:5)
将此用作全局操作过滤器。
public class NoCacheForAuthenticatedUsersAttribute: ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
if(filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
}
}
}
答案 1 :(得分:3)
使用HttpCachePolicy.AddValidationCallback。
请参阅:http://msdn.microsoft.com/en-us/library/system.web.httpcachepolicy.addvalidationcallback.aspx
答案 2 :(得分:2)
从您发布的Link1中获取灵感,因为易于编码的想法是您可以更改GetVaryByCustomString覆盖的输出,如下所示:
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";
}
}
return Guid.New().ToString();
}
else
{
return base.GetVaryByCustomString(context, arg);
}
}
这不是一个真正的答案,因为从技术上讲,经过身份验证的用户的输出仍然会被缓存,但它确实满足了经过身份验证的用户立即查看结果的要求。缺点是你需要保持缓存持续时间/ TTL足够小,这样你的缓存就不会被淹没,但足够大,匿名用户可以从中获得一些好处。
另一种方法是编写自己的Action Filter来进行缓存,并在那里添加对匿名缓存的支持。尽管如此,这更像是“滚动你自己”的领域。有关起点,请参阅此Klopfenstein's old post或Steve Sanderson's。它们缺少OutputCache的许多其他功能(例如,它在整个路径数据上键入),但您可以根据自己的规格使其工作。
答案 3 :(得分:0)
您可能需要创建两个控制器,一个用于经过身份验证的用户(不缓存的位置),一个用于未经过身份验证的用户(缓存的位置)。然后,您可以将控制器中的逻辑折射到一个通用的“业务层对象”,以保持代码DRY和单元可测试。