How to "invalidate" portions of ASP.NET MVC output cache?
Is there a way to programmatically invalidate portions of the ASP.NET MVC output cache? What I would like to be able to do is, if a user posts data that changes what would be returned from a cached action, be able to invalidate that cached data.
Is this even possible?
Solution 1:
One way is to use the method :
HttpResponse.RemoveOutputCacheItem("/Home/About");
Another way is described here : http://aspalliance.com/668
I think you could implement the second method by using a method level attribute for every action that you want and just add to it the string representing the key. That's if I understood your question.
Edit: Yes the asp.net mvc OutputCache is just a wrapper .
If you're using varyByParam="none"
then you just invalidate "/Statistics"
- that's if <id1>/<id2>
are querystring values. This will invalidate all versions of the page.
I did a quick test and if you add varyByParam="id1"
and then create multiple versions of the page - if you say invalidate invalidate "/Statistics/id1"
it will invalidate just that version. But you should do further tests.
Solution 2:
I did some test on caching. This is what I found:
You have to clear the cache for every route that lead to your action. If you have 3 routes that lead to the exact same action in your controller, you will have one cache for each route.
Let's say, I have this route config:
routes.MapRoute(
name: "config1",
url: "c/{id}",
defaults: new { controller = "myController", action = "myAction", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Defaultuser",
url: "u/{user}/{controller}/{action}/{id}",
defaults: new { controller = "Accueil", action = "Index", user = 0, id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Accueil", action = "Index", id = UrlParameter.Optional }
);
Then, these 3 routes lead to myAction
in myController
with the param myParam
:
- http://example.com/c/myParam
- http://example.com/myController/myAction/myParam
- http://example.com/u/0/myController/myAction/myParam
If my action is as follow
public class SiteController : ControllerCommon
{
[OutputCache(Duration = 86400, VaryByParam = "id")]
public ActionResult Cabinet(string id)
{
return View();
}
}
I will have one cache for each route (in this case 3). Therefore, I will have to invalidate every route.
Like this
private void InvalidateCache(string id)
{
var urlToRemove = Url.Action("myAction", "myController", new { id});
//this will always clear the cache as the route config will create the path
Response.RemoveOutputCacheItem(urlToRemove);
Response.RemoveOutputCacheItem(string.Format("/myController/myAction/{0}", id));
Response.RemoveOutputCacheItem(string.Format("/u/0/myController/myAction/{0}", id));
}