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

41

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

[OutputCache]
public controllerA(){}

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

public controllerB(){} // Calling this invalidates the cache
2个回答

61
你可以使用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");
    }
}

Index操作的响应在服务器上缓存1分钟。如果您点击InvalidateCacheForIndexAction操作,它将使Index操作的缓存过期。目前没有办法使整个缓存无效,您应该按每个被缓存的操作(而不是控制器)来处理,因为RemoveOutputCacheItem方法需要缓存的服务器端脚本的URL。


3
如何实现 Location = OutputCacheLocation.Client,还有其他特定的参数/方法吗? - Anuj Pandey
3
e10,你不能从服务器上删除在客户端浏览器缓存的数据。这是没有意义的。 - Darin Dimitrov
抱歉打扰,我有一个问题。当数据库更新时如何使内存缓存失效?你是否使用服务经常进行检查,然后如何清除缓存? - Shaiju T
3
@DarinDimitrov 我能在客户端清除缓存吗?我很难找到任何关于这方面信息的文章。 - Rajshekar Reddy
1
@AnkushJain,我正在使用Redis缓存通过输出缓存来存储缓存页面,对于每个应该被缓存的响应动作(包括动作中的参数),它会生成唯一的键并将序列化内容存储在redis的该键上。 - Ashish Shukla
显示剩余2条评论

0
你可以使用自定义属性来实现,如下所示:

[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
{
}

3
这将使客户端缓存失效。但是如果控制器A的视图被缓存在服务器上(这是默认行为),会怎样呢? - Darin Dimitrov
@DarinDimitrov 这将强制客户端从服务器获取一个新的未缓存版本。 - Mathew Thompson
1
是的,这是ControllerB的问题。但他想知道如何在原本使用OutputCache属性装饰的ControllerA中实现此操作。由于您已经使用NoCache属性装饰了ControllerB,因此它永远不会被缓存,但我认为这不是这里所要求的。他想知道如何在有人发送请求到ControllerB时使ControllerA的缓存失效,以便对ControllerA的后续请求不再进行缓存。 - Darin Dimitrov
3
我需要使服务器缓存失效,如果可能的话,我想知道是否可以使所有控制器的缓存全部失效。 - GibboK

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