我正在开发一个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
中设置响应缓存标头之前是否必须检查扩展名?还是有更简单的方法(例如完全绕过静态文件的请求管道)?
答案 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
为空。