如何关闭MVC请求的缓存,而不是IIS7中的静态文件?

时间:2010-11-02 13:17:59

标签: c# .net asp.net-mvc caching iis

我正在开发一个ASP.NET MVC应用程序。大多数控制器操作都不应该被缓存。因此,我在Application_BeginRequest输出了无缓存标头:

    protected void Application_BeginRequest()
    {
        HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        HttpContext.Current.Response.Cache.SetValidUntilExpires(false);
        HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        HttpContext.Current.Response.Cache.SetNoStore();
    }

应用程序在IIS7上运行,模块配置设置为runAllManagedModulesForAllRequests="true"。这意味着所有静态文件也会通过请求管道(并禁用缓存)。

为这些静态文件启用缓存的最佳方法是什么?在Application_BeginRequest中设置响应缓存标头之前是否必须检查扩展名?还是有更简单的方法(例如完全绕过静态文件的请求管道)?

2 个答案:

答案 0 :(得分:3)

您可以使用缓存过滤器属性将其应用于所有操作(通过基本控制器或在每个控制器或操作上显式)。这不适用于您的静态文件。

可能[CacheFilter]:

using System;
using System.Web;
using System.Web.Mvc;

    public class CacheFilterAttribute : ActionFilterAttribute
    {

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;

            cache.SetExpires(DateTime.UtcNow.AddDays(-1));
            cache.SetValidUntilExpires(false);
            cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
            cache.SetCacheability(HttpCacheability.NoCache);
            cache.SetNoStore();
        }
    }

另外,您甚至可以从其他域提供静态文件,例如sstatic.net这样做,这可以消除您的问题作为副作用。

答案 1 :(得分:3)

假设您无法避免在Hector的链接中使用runAllManagedModulesForAllRequests="true",您可以检查请求处理程序的类型,并且只有在MVC处理请求时才设置缓存头。

protected void Application_PreRequestHandlerExecute()
{
    if ( HttpContext.Current.CurrentHandler is MvcHandler )
    {
        HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        HttpContext.Current.Response.Cache.SetValidUntilExpires(false);
        HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        HttpContext.Current.Response.Cache.SetNoStore();
    }
}

请注意,我已将代码移至Application_PreRequestHandlerExecute,因为尚未在BeginRequest中选择处理程序,因此HttpContext.Current.CurrentHandler为空。