2

In our code we have an MVC controller action that is decorated with the OutputCacheAttribute. Is there any way in some other action to clear the cache for the first action?

2 Answers 2

3

It depends. If it is a child action the cache is stored in the MemoryCache and the only way to clear it is undocumented and involves busting the whole memory cache:

OutputCacheAttribute.ChildActionCache = new MemoryCache("NewDefault");

The drawback of course is that this removes all cached child actions and not just the cached output of this child action. If it is a normal action then you could use the Response.RemoveOutputCacheItem method by passing it the url of the action that was cached. You might also find the following article interesting.

Caching in ASP.NET MVC 3 has still a very long way to go. Hopefully they are improving many things in ASP.NET MVC 4 and simplifying it.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I'll have to check out that article.
0

Yes, it is possible I have found the answer in this book. See 14.3 Output Cache In ASP.NET MVC page 372 - Deterministically removing items from cache

When we decorate an action with the OutputCacheAttribute , OutputCache stores its result into ASP.NET Cache and automatically recovers it when it must serve a subse- quent analogous request. If we knew which cache key the page belongs to, we could easily remove it. Unfortunately, this isn’t easily possible, and even if it were, we aren’t supposed to know it because it resides in the internal logic of the caching infrastruc- ture and might change without notice in future releases. What we can do, though, is leverage the cache dependencies mechanism to achieve a similar result. This feature is similar to the change monitors we’re going to talk about in section 14.4. Leveraging cache dependencies consists of tying one cache entry to another to automatically remove the first one when the latter is invalidated.

And a piece of code

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;
}
}

And Remove cache dependency attribute

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);
}
}

and finally use it

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

where

public class Story { 
  int id {get;set;} //case is important
  string storyContent{get;set;}
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.