我想在我的ASP.NET(MVC)应用中将Cache-Control
标头设置为public
。问题是以前设置缓存策略的代码(我无法改变):
var response = htmlHelper.ViewContext.HttpContext.Response;
response.Cache.SetExpires(System.DateTime.UtcNow.AddDays(-1));
response.Cache.SetValidUntilExpires(false);
response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
response.Cache.SetCacheability(HttpCacheability.NoCache);
response.Cache.SetNoStore();
我以后找不到覆盖它的方法,因为无论我如何尝试设置缓存控制,上面的内容都会生效。例如。以下两种方法都不能阻止先前禁用的缓存:
httpContext.Response.Headers["Cache-Control"] = "public";
var cache = httpContext.Response.Cache;
cache.SetExpires(cacheItem.ValidUntilUtc);
cache.SetValidUntilExpires(true);
cache.SetRevalidation(HttpCacheRevalidation.None);
cache.SetCacheability(HttpCacheability.Public);
cache.SetMaxAge(cacheItem.ValidUntilUtc - _clock.UtcNow);
有没有办法以某种方式覆盖或重置缓存策略?
答案 0 :(得分:3)
显然这不可能,因为HttpCachePolicy
会主动阻止你设置更高的" cachability,即如果你设置NoCache后尝试设置Public,则不会发生任何事情。
似乎唯一的,hackish方式是使用私有反射并调用内部Reset
方法如下:
var cache = httpContext.Response.Cache;
var cachePolicy = (HttpCachePolicy)typeof(HttpCachePolicyWrapper).InvokeMember("_httpCachePolicy", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField, null, cache, null);
typeof(HttpCachePolicy).InvokeMember("Reset", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, cachePolicy, null);
cache.SetCacheability(HttpCacheability.Public);
答案 1 :(得分:0)
在您的第一个代码示例中,看起来在HTML Helper中设置了缓存属性,这很可能是以某种方式在视图上呈现的。我猜你试图覆盖属性太早发生,然后被覆盖在视图的渲染上。
显然,更改设置这些标头的代码是最好的。如果你绝对不能,我会看到一些前进的路线:
不要立即从控制器返回视图。你可能有类似的东西:
public ActionResult MyAction() {
// code here
return View();
}
将其转为,然后您可以尝试在视图中覆盖缓存:
public ActionResult MyAction() {
// code here
var result = View();
ResetCaching();
return result;
}
如果这不起作用,请在控制器中使用OnResultExecuted
或OnActionExecuted
来捕获视图何时完成执行或操作已执行并尝试在视图后覆盖缓存和/或行动已经执行但在控制器处理之前。
您可以实现custom action filter,而不是覆盖控制器上的实际事件,这可以使代码更清晰,并允许您在多个位置重复使用它。
绝对最坏的情况,请使用Application_PreSendRequestHeaders
文件中的global.asax
事件,如果请求符合重置缓存的要求,请在将标头发送到浏览器之前修改标头。此方法将使您检查通过应用程序的每个请求。