ASP.NET Output Caching not working after upgrade from MVC2 to MVC4

Topics: ASP.NET MVC
Jul 24, 2012 at 5:07 AM

We have an existing MVC2 project that we just upgraded to MVC4 following first these steps to get to MVC3, then these steps to get to MVC4.

Output caching had been successfully working for a long time in our MVC2 project, but it does not work after the MVC4 version.

I've added a simple controller to test caching:

 public class TestController : Controller
 {
    [OutputCache(Duration = 600, VaryByParam = "*")]
    public ActionResult CacheTest()
    {
        return Content(DateTime.Now.ToLongTimeString());
    }
 }

Each time i request /Test/CacheTest in a browser, the time output to the browser changes.

Creating a new MVC3 project in this same solution, then upgrading to MVC4, then copying this same code over works as expected.

So there must be something somewhere in our existing code or configuration that is breaking output caching.

I've also tried stripping out a ton of stuff from the web.config file thinking something there was causing problems - no luck.

Rendering the CacheTest action above in any view will display cached results - i.e. the date does not change on each refresh:

<% Html.RenderAction("CacheTest", "Test"); %>

Why does that work, but the action url from a browser is never cached?

Any suggestions on how to fix or debug?

Thanks.

Coordinator
Jul 24, 2012 at 7:07 AM

Hi,

This definitely looks wrong - we'll investigate and see if we can figure out what's going on here.

Thanks,

Eilon

 

Jul 24, 2012 at 7:52 AM

So it seems IsChildAction is not true when the OutputCacheAttribute.OnActionExecuting is being called, so caching is skipped.  This also explains why when i call Html.RenderAction caching works.

I could maybe understand some compatibility problems if i was still using the standard MVC2 Site.Master and aspx view engine (which i was and caching was not working).

However, i added a Razor _Layout.cshtml and a razor view to my project, and still no dice. 

Under what conditions should ControllerContext.IsChildAction be true when rendering an action?

Jul 24, 2012 at 3:49 PM
OutputCacheAttribute actually uses two different caching mechanisms, depending on whether the request is a child action or not. The fact that it skips the code that's used for child actions when this isn't a child action isn't itself a bug. (IsChildAction will only be true when you've called RenderAction.)
Jul 24, 2012 at 6:08 PM

@BradWilson

Thanks for the reply. 

Can you point me to some area in the code where a different caching path is taken?   The OnActionExecuting, OnResultExecuting, OnActionExecuted, and OnResultExecuted in OutputCacheAttribute all check filterContext.IsChildAction.

I also tried adding the OutputCache directive a view and the view is still not cached.

Jul 25, 2012 at 12:32 AM
OnResultExecuting runs for non-child actions. The others run for child actions. The bulk of the caching work for non-child actions is actually done by the page caching system built into ASP.NET, which is why it looks like most of the code in OutputCacheAttribute is related to child actions.
Oct 15, 2012 at 2:35 PM

Hi, I have the same problem as jaminto.

Caching stopped working after upgrading of my project from MVC3 to MVC4!

Please is there any workaround? Did you solve the problem, jaminto?