我有一个关于如何以编程方式指示ASP.NET跳过从输出缓存中解析请求的问题。
想象一下,您通过在运行时将缓存策略设置从CMS应用到HttpResponse来缓存页面输出(例如http://domain/page.aspx)。在每个请求的基础上取决于即当前用户是否经过身份验证+一组已知组的成员(或由业务逻辑匹配),我想指示ASP.NET 跳过解析来自输出缓存的请求。
场景是两个不同的用户同时(或更多)在系统上。用户A经过身份验证+一组已知组的成员,用户B是匿名用户。无论缓存的页面是什么,我都希望经过身份验证的用户浏览所有页面,就像没有启用输出缓存一样 - 永远;同时,我希望ASP.NET继续为匿名用户(或者与业务逻辑不匹配的用户)提供输出缓存页面。
典型的建议是使用VaryByHeader,VaryByParam等并污染输出缓存 - 不好,但是在使用Reflector挖掘输出缓存模块时,我注意到输出缓存模块跳过当前请求,以防几个存在已知的“缓存控制”头部。至于我关注标题,如果用户强制通过在地址栏中点击F5或ENTER来呈现新的副本,则会从浏览器发送这些标题。
所以,我正在做的只是在输出缓存订阅的ResolveRequestCache事件之前的事件中,在自定义http模块中将“cache-control”标头设置为“no-cache”。像这样:
context.Request.Headers["Cache-Control"] = "no-cache";
一切都很好,但是,如果设置了HttpCachePolicy.SetValidUntilExpires(true)缓存策略,ASP.NET将忽略先前设置的请求标头并从输出缓存中提供请求。
作为替代方案,我想我可以在同一个http模块中的后处理事件中编写其他代码,以确保调用HttpCachePolicy.SetValidUntilExpires(false),以防配置输出缓存,但我认为它会是一个更干净的解决方案,实际上能够指示ASP.NET简单地跳过从输出缓存中解析请求。我可以想象这个问题有很多尴尬的解决方案,但我追求的是正确的。
作为参考,我一直在尝试HttpCachePolicy类的大多数相关方法,例如:
HttpResponse.Cache.SetNoServerCaching()).
答案 0 :(得分:3)
您可以在应用程序中添加HttpCacheValidateHandler,您可以在其中实现所需的任何逻辑。它将在ResolveRequestCache
事件期间执行,该事件在执行身份验证和授权后触发。关键是在您要绕过缓存的情况下返回HttpValidationStatus.IgnoreThisRequest
。
请参阅此示例HttpModule以供参考:
public class CacheModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest +=
(s, e) => context.Context.Response.Cache
.AddValidationCallback(CacheHandler, null);
}
private static void CacheHandler(
HttpContext context, object data,
ref HttpValidationStatus validationstatus)
{
// bypass cache for all users with skipCache cookie
validationstatus =
context.Request.Cookies["skipCache"] != null
? HttpValidationStatus.IgnoreThisRequest
: HttpValidationStatus.Valid;
}
public void Dispose()
{
}
}
答案 1 :(得分:0)
我不确定在缓存某些内容后是否支持这样做的方法。
但是你为什么不喜欢VaryByHeader选项呢?假设有一个标题,您可以查看以区分已登录和未登录的用户,这应该有效。如果您有逻辑仅在用户未登录时填充输出缓存,则不会污染缓存。登录用户总是会遇到缓存未命中。