Mvc3 OutputCache RemoveOutputCacheItem RenderAction

I did my research but could not find the answers.

I am using Html.RenderAction on the main page (to display the page title with links specific to user permissions). The action is decorated with OutputCache, returns partial control, and is cached as expected.

When an event occurs (let's say permissions are changed) I want to programmatically invalidate the cached partial control.

I am trying to use the RemoveOutputCacheItem method. It takes a path as a parameter. I am trying to set the path to the action used in Html.RenderAction. This does not cancel the action.

How can I programmatically invalidate an action?

thanks

+7
source share
2 answers

The cache for child actions is stored in the OutputCacheAttribute.ChildActionCache property. The problem is that the API that generates identifiers for child actions and stores them in this object is not publicly available (WHY Microsoft?). Therefore, if you try to skip objects in this collection, you will find that it will also contain a cached value for your action with the child, but you cannot identify it unless you reverse engineer the algorithm used to generate keys that look like something something like this (as seen with Reflector):

internal string GetChildActionUniqueId(ActionExecutingContext filterContext) { StringBuilder builder = new StringBuilder(); builder.Append("_MvcChildActionCache_"); builder.Append(filterContext.ActionDescriptor.UniqueId); builder.Append(DescriptorUtil.CreateUniqueId(new object[] { this.VaryByCustom })); if (!string.IsNullOrEmpty(this.VaryByCustom)) { string varyByCustomString = filterContext.HttpContext.ApplicationInstance.GetVaryByCustomString(HttpContext.Current, this.VaryByCustom); builder.Append(varyByCustomString); } builder.Append(GetUniqueIdFromActionParameters(filterContext, SplitVaryByParam(this.VaryByParam))); using (SHA256 sha = SHA256.Create()) { return Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(builder.ToString()))); } } 

So you can do the following madness:

 public ActionResult Invalidate() { OutputCacheAttribute.ChildActionCache = new MemoryCache("NewDefault"); return View(); } 

which, obviously, will invalidate all cached actions, which might not be what you are looking for, but I'm afraid that this is the only way, except, of course, reverse engineering key generation :-).

@Microsoft, please, I ask you for ASP.NET MVC 4.0:

  • introduce the ability to cache donuts in addition to caching holes in the don.
  • introduce the ability to easily end the result of the action of the cached controller (something more MVCish than Response.RemoveOutputCacheItem )
  • introduce the ability to easily complete the result of a cached child action
  • if you follow 1. then, obviously, imagine expiring the donut cache.
+9
source

You might want to approach this differently. You can create a custom AuthorizeAttribute attribute - it will simply allow everyone - and add an override to the OnCacheValidation method to enable your logic. If the underlying OnCacheValidation returns HttpValidationStatus.Valid, then do your check to see if the state has changed and if so, return HttpValidationStatus.Invalid instead.

 public class PermissionsChangeValidationAttribute : AuthorizeAttribute { public override OnAuthorization( AuthorizationContext filterContext ) { base.OnAuthorization( filterContext ); } public override HttpValidationStatus OnCacheAuthorization( HttpContextBase httpContext ) { var status = base.OnCacheAuthorization( httpContext ); if (status == HttpValidationStatus.Valid) { ... check if the permissions have changed somehow if (changed) { status = HttpValidationStatus.Invalid; } } return status; } } 

Note that there are ways to pass additional data during the cache check process if you need to track the previous state, but you will need to replicate some code in the base class and add your own cache checker. You can share some ideas on how to do this from my blog post about creating a custom attribute authorize: http://farm-fresh-code.blogspot.com/2011/03/revisiting-custom-authorization-in.html

+2
source

All Articles