在我们的代码中,我们有一个用OutputCacheAttribute
修饰的MVC控制器动作。在其他一些操作中是否有任何方法可以清除第一个操作的缓存?
答案 0 :(得分:2)
这取决于。如果是子操作,则缓存存储在MemoryCache中,清除它的唯一方法是未记录的,并且涉及破坏整个内存缓存:
OutputCacheAttribute.ChildActionCache = new MemoryCache("NewDefault");
当然,缺点是这会删除所有缓存的子操作,而不仅仅是此子操作的缓存输出。如果这是正常操作,那么您可以使用Response.RemoveOutputCacheItem方法将其传递给缓存的操作的url。您可能还会发现following article有趣。
ASP.NET MVC 3中的缓存还有很长的路要走。希望他们在ASP.NET MVC 4中改进很多东西并简化它。
答案 1 :(得分:0)
是的,有可能 我在this book找到了答案。 请参见ASP.NET MVC中的14.3输出缓存 第372页 - 确定性地从缓存中删除项目
当我们使用OutputCacheAttribute,OutputCache装饰一个动作时 将其结果存储到ASP.NET缓存中并自动恢复它 什么时候它必须服务于后续的类似请求。如果我们知道哪个 页面所属的缓存键,我们可以轻松删除它。 不幸的是,这不容易实现,即使是这样,我们也是如此 我不应该知道它,因为它存在于内部逻辑中 缓存基础设施可能会在没有通知的情况下发生变化 未来版本。但是,我们可以做的是利用缓存 依赖机制实现类似的结果。这个功能是 类似于我们将在章节中讨论的变更监视器 14.4。利用缓存依赖性包括将一个缓存条目绑定到另一个缓存条目,以便在后者失效时自动删除第一个缓存条目。
一段代码
public class DependencyOutputCacheAttribute : OutputCacheAttribute
{
public string ParameterName { get; set; }
public string BasePrefix { get; set; }
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting( filterContext );
string key = string.IsNullOrEmpty( BasePrefix )
? filterContext.RouteData.Values["action"] + "_" + filterContext.RouteData.Values["controller"]
: BasePrefix;
key = AddToCache( filterContext, key, ParameterName);
}
private string AddToCache(ResultExecutingContext filterContext, string key, string parameter)
{
if ( !string.IsNullOrEmpty( parameter ) && filterContext.RouteData.Values[parameter] != null) {
key += "/" + filterContext.RouteData.Values[parameter];
filterContext.HttpContext.Cache.AddBig( key, key );
filterContext.HttpContext.Response.AddCacheItemDependency( key );
}
return key;
}
}
删除缓存依赖关系属性
public class RemoveCachedAttribute : ActionFilterAttribute
{
public string ParameterName { get; set; }
public string BasePrefix { get; set; }
public override void OnResultExecuting( ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
string key = string.IsNullOrEmpty(BasePrefix) ?
filterContext.RouteData.Values["action"].ToString() + "_" +
filterContext.RouteData.Values["controller"].ToString() : BasePrefix;
if (!string.IsNullOrEmpty(ParameterName))
key += filterContext.RouteData.Values[ParameterName];
filterContext.HttpContext.Cache.Remove(key);
}
}
最后使用它
[DependencyCache( BasePrefix = "Story", ParameterName = "id" )]
public virtual ActionResult ViewStory(int id){
//load story here
}
[HttpPost, RemoveCache( BasePrefix = "Story", ParameterName = "id" )]
public virtual ActionResult DeleteStory(int id){
//submit updated story version
}
[HttpPost, RemoveCache( BasePrefix = "Story", ParameterName = "id" )]
public virtual ActionResult EditStory(Story txt){
//submit updated story version
}
,其中
public class Story {
int id {get;set;} //case is important
string storyContent{get;set;}
}