如何使控制器中的缓存数据 [OutputCache] 无效?

Posted

技术标签:

【中文标题】如何使控制器中的缓存数据 [OutputCache] 无效?【英文标题】:How to invalidate cache data [OutputCache] from a Controller? 【发布时间】:2013-04-18 03:08:42 【问题描述】:

使用 ASP.Net MVC 3 我有一个控制器,它的输出使用属性 [OutputCache] 进行缓存

[OutputCache]
public controllerA()

我想知道是否可以通过调用另一个控制器来使特定控制器的缓存数据(服务器缓存)或所有缓存数据无效

public controllerB() // Calling this invalidates the cache

【问题讨论】:

【参考方案1】:

您可以使用RemoveOutputCacheItem 方法。

这是一个如何使用它的示例:

public class HomeController : Controller

    [OutputCache(Duration = 60, Location = OutputCacheLocation.Server)]
    public ActionResult Index()
    
        return Content(DateTime.Now.ToLongTimeString());
    

    public ActionResult InvalidateCacheForIndexAction()
    
        string path = Url.Action("index");
        Response.RemoveOutputCacheItem(path);
        return Content("cache invalidated, you could now go back to the index action");
    

索引操作响应在服务器上缓存 1 分钟。如果您点击InvalidateCacheForIndexAction 操作,它将使索引操作的缓存过期。目前没有办法使整个缓存失效,你应该根据缓存的操作(而不是控制器)来做,因为RemoveOutputCacheItem 方法需要它缓存的服务器端脚本的 url。

【讨论】:

谢谢达林,非常感谢您的帮助! 如何实现这个 -> Location = OutputCacheLocation.Client ,还有其他具体的参数/方法吗? e10,您无法从服务器中删除缓存在客户端浏览器上的数据。这没有意义。 @DarinDimitrov 我可以清除客户端的缓存吗?我发现很难找到包含该信息的任何文章。 @AnkushJain ,我正在使用 Redis 缓存通过输出缓存存储缓存的页面,对于应该缓存的每个动作(包括动作中的参数)响应,它会生成唯一键并存储redis 中该键上的序列化内容。【参考方案2】:

您可以通过使用自定义属性来做到这一点,如下所示:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : ActionFilterAttribute

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        base.OnResultExecuting(filterContext);
    

然后在您的controllerb 上您可以:

[NoCache]
public class controllerB


【讨论】:

这将使客户端缓存失效。但是如果 ControllerA 的视图缓存在服务器上(这是默认行为)呢? @DarinDimitrov 这将强制客户端从服务器获取一个新的 uncached 版本。 是的,属于 ControllerB。但他问的是如何使用 ControllerA 来做到这一点,这是首先装饰有 OutputCache 属性的那个。由于您使用 NoCache 属性装饰了 ControllerB,因此它永远不会被缓存,但我认为这不是这里要问的。他想知道当有人向ControllerB发送请求时,如何使ControllerA的缓存失效,从而使后续对ControllerA的请求不再被缓存。 我需要使服务器缓存失效,如果可能的话,我想知道是否可以为所有控制器失效所有缓存

以上是关于如何使控制器中的缓存数据 [OutputCache] 无效?的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET-缓存outputcache参数

列出 OutputCache 条目

IIS(动态和静态)缓存、OutPutCache 和浏览器缓存有啥区别

ASP.NET 页面缓存OutputCache用法实例(附ab压力测试对比图)

C# - 缓存OutputCache基础配置

ASP.NET MVC 阻止当前请求的视图页面缓存OutputCache