【问题标题】:Override ASP.NET cache policy and set Cache-Control to public覆盖 ASP.NET 缓存策略并将 Cache-Control 设置为 public
【发布时间】:2015-07-01 18:33:36
【问题描述】:

我想在我的 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);

有没有办法以某种方式覆盖或重置缓存策略?

【问题讨论】:

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


    【解决方案1】:

    在您的第一个代码示例中,看起来缓存属性是在 HTML 帮助程序中设置的,该帮助程序很可能以某种方式呈现在视图上。我猜您尝试覆盖属性的尝试发生得太早,然后在视图呈现时被覆盖。

    显然,最好更改设置这些标头的代码。如果你绝对不能,我看到了一些前进的路线:

    1. 不要立即从控制器返回视图。你可能有类似的东西:

      public ActionResult MyAction() {
          // code here
      
          return View();
      }
      

      把它变成这样你就可以尝试覆盖视图中的缓存:

      public ActionResult MyAction() {
          // code here
      
          var result = View();
          ResetCaching();
          return result;
      }
      
    2. 如果这不起作用,请在控制器中使用 OnResultExecutedOnActionExecuted 来捕获视图已完成执行或操作已执行并尝试在视图和/或操作之后覆盖缓存已执行,但在控制器被处置之前。

      您可以实现custom action filter,而不是覆盖控制器上的实际事件,这可以保持代码更简洁,并允许您在多个地方重用它。

    3. 绝对最坏的情况,在global.asax 文件中使用Application_PreSendRequestHeaders 事件,如果请求满足重置缓存的要求,请在将标头发送到浏览器之前对其进行修改。此方法将使您检查通过您的应用程序的每个请求。

    【讨论】:

    • 谢谢,但这不是问题所在。顺序是正确的,即我的代码在导致问题的代码之后运行(它实际上是在 OnResultExecuted 的结果过滤器中执行的)。导致我尝试失败的原因是,一旦设置为 NoCache HttpCachePolicyBase 将不允许您启用缓存。
    • @Piedone 我不知道它阻止了你重置它,对此感到抱歉。在阅读了HttpCachePolicy 的源代码后,我没有看到官方的重置方法。如果您有兴趣使用反射,This answer 确实向您展示了如何修改策略的内部属性以重置事物。
    • 谢谢,是的,这就是我最终所做的。将添加一个答案。
    【解决方案2】:

    显然这不可能,因为HttpCachePolicy 会主动阻止您设置“更高”的可缓存性,即如果您在设置 NoCache 之后尝试设置 Public,则不会发生任何事情。

    似乎唯一的黑客方法是使用私有反射并调用内部 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);
    

    【讨论】:

      猜你喜欢
      • 2021-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      相关资源
      最近更新 更多