Output Caching Actions Gotcha in ASP.NET MVC 3
Posted by: Malcolm Sheridan
in Category ASP.NET MVC
Abstract: The following goes through describes how to avoid the output caching problem in ASP.NET MVC 3.
This is a gotcha I had to write about. Everyone knows the benefits of caching data when working with the web. Be it file caching, donut caching or SQL Server caching, the benefits are obvious; retrieving data from memory instead of a data store means a more performance. I recently had an action that was being used frequently, so I decided to cache the action. I was trying to use a cache profile for this. I’ve used them previously in ASP.NET and the benefits of using them are incontrovertible. Moving configurable code into the web.config just makes sense.
I’ll change the real code I was using to something simple, so the action method looked like this.
And if I called that action with the following code, things worked as expected.
Now if you try to code according to better coding practices, you’d move the caching code into a cache profile. So here’s the cache profile in web.config.
Next is to update the action to use the cache profile.
Now if you run the website, you’ll encounter the Yellow Screen of Death.
Duration must be a positive number. I doubled checked the web.config to make sure I add this value, and yes I did. After much stumbling around, I peeked inside of the MVC 3 source code and looked at the OutputCacheAttribute class and found the ValidateChildActionConfiguration method.
This method is called during the OnActionExecuting event.
ValidateChildActionConfiguration throws an error if you don’t have the Duration and VaryByParam values set.
What’s the way around this? Well you can either stick to hard coding the values in the OutputCache attribute. There’s nothing wrong with that. Another option is to implement your own cache attribute. You can implement this in ASP.NET 4.0 if you create your own OutputCacheProvider object. Personally having to do this myself makes me reluctant as this is plumbing code, and I expect that it should be dealt with by the framework.
The entire source code of this article can be downloaded over here