ASP.NET中的条件输出缓存

And*_*rum 5 asp.net caching outputcache

我有一个问题,如何以编程方式指示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";
Run Code Online (Sandbox Code Playgroud)

但是,如果设置了HttpCachePolicy.SetValidUntilExpires(true)高速缓存策略,则ASP.NET将忽略先前设置的请求标头并从输出高速缓存提供请求.

作为替代方案,我想我可以在同一个http模块中的后处理事件中编写额外的代码,以确保调用HttpCachePolicy.SetValidUntilExpires(false),以防配置输出缓存,但我认为它会更多干净的解决方案实际上能够指示ASP.NET简单地跳过从输出缓存中解析请求.我可以想象这个问题有很多尴尬的解决方案,但我追求的是正确的.

作为参考,我一直在尝试HttpCachePolicy类的大多数相关方法,例如:

HttpResponse.Cache.SetNoServerCaching()).
Run Code Online (Sandbox Code Playgroud)

Oli*_*ver 5

您可以将HttpCacheValidateHandler添加到您的应用程序中,您可以在其中实现您想要的任何逻辑。它将ResolveRequestCache在身份验证和授权执行后触发的事件期间执行。关键是HttpValidationStatus.IgnoreThisRequest在你想绕过Cache的情况下返回。

请参阅此示例 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()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)