如何在程序中清除控制器操作方法的输出缓存

71

如果控制器操作在操作上指定了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)来清除缓存,但我无法确定路径应该映射到哪个操作方法。如果我无法解决这个问题,可能只需将RenderToString的输出手动插入到HttpContext.Cache中。

更新

请注意,OutputCache是按参数变化而定的,测试硬编码路径“/controller/action”实际上不能清除缓存,因此它看起来必须匹配“/controller/action/param1/param2”。

这意味着我可能需要回退到对象级别的缓存,并手动缓存RenderToString()的输出 :(


1
尝试在OutputCache属性中添加location="Server" - 你无法从服务器清除客户端的缓存。 - eu-ge-ne
5个回答

61

试试这个

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。唉。 - marcel_g
2
我想我已经回答了自己的问题:https://dev59.com/EnVD5IYBdhLWcg3wWKLc#2876701 - Kevin
9
注意,在MVC3中,您现在需要使用Location = OutputCacheLocation.Server并包括System.Web.UI'Location="Server"将不再编译通过。 - Rondel
使用location=client后,它第一次之后就不会调用action方法了。但是我有一个问题,使用location=server时,它也调用了action方法。这是正确的吗?还是不应该调用action方法? - chitra
@eu-ge-ne,我不明白如何在注销时清除页面缓存,而且我希望可以从网站的任何页面注销。 - Mohit Shah
显示剩余5条评论

8
进一步支持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()时,它们会防止当前请求被缓存。除非对这些请求也调用这些函数,否则后续请求将被缓存。
这对于处理错误情况非常理想-通常情况下您希望缓存响应,但如果它们包含错误消息,则不希望缓存。

5
我认为正确的流程应该是:

filterContext.HttpContext.Response.Cache.SetNoStore()

谢谢,这是一个更好的答案,因为它适用于所有位置。Response.Cache.SetNoStore() - user1023602

4
在AjaxHtmlOutputMethod中添加代码
HttpContext.Cache.Insert("Page", 1);
Response.AddCacheItemDependency("Page");

现在您可以使用以下方法清除输出缓存:

HttpContext.Cache.Remove("Page");

3
另一个选择是在OutputCache中使用VaryByCustom,并在那里处理特定缓存元素的失效。也许对你有用,但这不是解决问题的通用方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接