【问题标题】:How to programmatically clear outputcache for controller action method如何以编程方式清除控制器操作方法的输出缓存
【发布时间】:2010-11-13 03:57:27
【问题描述】:

如果控制器动作在动作上指定了 OutputCache 属性,有没有什么方法可以在不重启 IIS 的情况下清除输出缓存?

[OutputCache (Duration=3600,VaryByParam="param1;param2")]
public string AjaxHtmlOutputMethod(string param1, string param2)
{
  var someModel = SomeModel.Find( param1, param2 );

  //set up ViewData
  ...

  return RenderToString( "ViewName", someModel );
}

我正在考虑使用HttpResponse.RemoveOutputCacheItem(string path) 来清除它,但我无法弄清楚将它映射到操作方法的路径应该是什么。我将使用 ViewName 呈现的 aspx 页面再试一次。

如果我无法弄清楚这一点,我可能会手动将RenderToString 的输出插入HttpContext.Cache

更新

请注意,OutputCache 是 VaryByParam,测试硬编码路径“/controller/action”并不会真正清除 outputcache,因此看起来它必须匹配“/controller/action/param1/param2”。

这意味着我可能不得不恢复到对象级缓存并手动缓存 RenderToString() 的输出:(

【问题讨论】:

  • 尝试将location="Server"添加到OutputCache属性 - 你不能从服务器清除客户端的缓存

标签: asp.net asp.net-mvc


【解决方案1】:

试试这个

var urlToRemove = Url.Action("AjaxHtmlOutputMethod", "Controller");
HttpResponse.RemoveOutputCacheItem(urlToRemove);

更新:

var requestContext = new System.Web.Routing.RequestContext(
    new HttpContextWrapper(System.Web.HttpContext.Current),
    new System.Web.Routing.RouteData());

var Url = new System.Web.Mvc.UrlHelper(requestContext);

更新:

试试这个:

[OutputCache(Location= System.Web.UI.OutputCacheLocation.Server, Duration=3600,VaryByParam="param1;param2")]

否则缓存删除将不起作用,因为您已经 在用户机器上缓存 HTML 输出

【讨论】:

  • 当然,现在我无法弄清楚如何在具有该功能的 Web 服务中实例化 UrlHelper。参数。
  • 我放弃了那次尝试。我找不到任何方法让 RequestContext 传递给 UrlHelper 构造方法。所以我通过在“/controller/action”中的硬编码来测试它。这显示没有错误,但不会清除缓存。
  • 谢谢,不知道 HttpContextWrapper(),所以它实际上可以构建和运行。不幸的是,由于在方法属性上设置了 varybyparam,它仍然没有清除输出缓存,所以我最终使用包含参数的键来缓存 RenderToString 的输出以区分它。
  • 我想我已经回答了我自己的问题:stackoverflow.com/questions/11585/…
  • 只是一个注释。在 MVC3 中,您现在需要使用 Location = OutputCacheLocation.Server 并包含 System.Web.UI'Location="Server" 将不再编译。
【解决方案2】:

另一种选择是将VaryByCustom 用于OutputCache 并处理那里某些缓存元素的失效。

也许它对你有用,但它不是解决你问题的通用方法

【讨论】:

    【解决方案3】:

    我认为正确的流程是:

    filterContext.HttpContext.Response.Cache.SetNoStore()
    

    【讨论】:

    • 谢谢,这是一个更好的答案,因为它适用于所有位置。 Response.Cache.SetNoStore()
    【解决方案4】:

    将代码添加到 AjaxHtmlOutputMethod

    HttpContext.Cache.Insert("Page", 1);
    Response.AddCacheItemDependency("Page");
    

    现在可以使用清除输出缓存

    HttpContext.Cache.Remove("Page");
    

    【讨论】:

      【解决方案5】:

      进一步接受的答案,支持 VaryByParam 参数:

        [OutputCache (Duration=3600, VaryByParam="param1;param2", Location = OutputCacheLocation.Server)]
        public string AjaxHtmlOutputMethod(string param1, string param2)
        {
             object routeValues = new { param1 = param1, param2 = param2 };
      
             string url = Url.Action("AjaxHtmlOutputMethod", "Controller", routeValues);
      
             Response.RemoveOutputCacheItem(url);
        }
      

      不过 Egor 的回答要好得多,因为它支持所有 OutputCacheLocation 值:

        [OutputCache (Duration=3600, VaryByParam="param1;param2")]
        public string AjaxHtmlOutputMethod(string param1, string param2)
        {
             if (error)
             {
                 Response.Cache.SetNoStore(); 
                 Response.Cache.SetNoServerCaching();
             }
        }
      

      SetNoStore()SetNoServerCaching() 被调用时,它们会阻止当前请求被缓存。进一步的请求将被缓存,除非也为这些请求调用函数。

      这是处理错误情况的理想选择 - 当您通常想要缓存响应时,但如果它们包含错误消息则不是。

      【讨论】:

        猜你喜欢
        • 2018-01-10
        • 1970-01-01
        • 1970-01-01
        • 2012-01-08
        • 2011-07-22
        • 2011-02-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多