Output Cache In MVC.

In ASP.NET MVC there are many ways to cache data, in this blog I will take a look at the OutputCache and show you how to use it to help speed up your site.

To start, let's create our controller and public ActionResult.

[HttpGet]
[OutputCache(Duration = 10, VaryByParam = "*")]
public ActionResult MvcCachingExample()
{
string returnDateTime = DateTime.Now.ToString(CultureInfo.InvariantCulture);
TempData["DisplayDateTime"] = returnDateTime;

return View("~/Views/Caching/CachingView.cshtml");
}

As you can see in the code above, I have added the outputcache attribute to the action method and set the cache to expire after 10 seconds.

VaryByParam with id

VaryByParam is the parameter that we pass into the ASP.NET action, the * simple means cache all parameters, if we just want to cache one parameter, then we can use VaryByParam = "id", where id is the parameter of the action as seen in the code below.

[HttpGet]
[OutputCache(Duration = 10, VaryByParam = "id")]
public ActionResult MvcCachingExample(int id)
{
   string returnDateTime           = DateTime.Now.ToString(CultureInfo.InvariantCulture);
   TempData["DisplayDateTime"]     = returnDateTime;

    return View("~/Views/Caching/CachingView.cshtml");
}

So now you go and add the outputcache attribute to all your controller public ActionResults and you are feeling good.

But then the boss comes along and says we don't want to cache for 10 seconds anymore, we want to make it 1 hour or 3600 seconds.

the boss

Not a good idea now, having to go and change all attributes for your output caching. So how do we get around this, well say hello to CacheProfile, with the cacheprofile, we can add the caching to the web.config file under system.web, once done we now can change the controller action to the code below.


//Controller
 [HttpGet]
[OutputCache(CacheProfile = "CacheExample")]
public ActionResult MvcCacheProfileExample()
{
    string returnDateTime = DateTime.Now.ToString(CultureInfo.InvariantCulture);
    TempData["DisplayDateTime"] = returnDateTime;
    return View("~/Views/Caching/CachingProfileView.cshtml");
}

Cache Profile.

So once again we are feeling good, but again the boss comes along and says 'I don't like the name you have chosen for the profile'.

the boss

So you change the name in the web.config and also all the controller actions, but now you are getting wise and think the boss may come along and ask for something else to be changed.

To get around this, create a new controller and name it MasterController or any other name you see fit and add the attribute to the master and then change your original controller as per below.

using System.Web.Mvc;

namespace Web.Controller.Controllers
{
    [OutputCache(CacheProfile = "CacheExample")]
    public class MasterController : System.Web.Mvc.Controller
    {
    }
}

public class MvcCachingUsingMasterController : MasterController
    {
        [HttpGet]
        [OutputCache(CacheProfile = "CacheExample")]
        public ActionResult MvcCacheProfileExample()
        {
            string returnDateTime = DateTime.Now.ToString(CultureInfo.InvariantCulture);
            TempData["DisplayDateTime"] = returnDateTime;
            return View("~/Views/Caching/CachingProfileView.cshtml");
        }
}

Error.

So again we are feeling good, we only need to change the output cache duration in one place, so any time we need to change the expiration time it can easily be done.

But wait a minute, on one of our controllers, we are returning a partials view with a RenderAction in the view, but we get the following error. 

OutputCacheAttribute for child actions only supports Duration, VaryByCustom, and VaryByParam values. Please do not set CacheProfile, Location, NoStore, SqlDependency, VaryByContentEncoding, or VaryByHeader values for child actions.

Output Cache In MVC

So when using CacheProfile, don't try and use it with a RenderAction as you will receive the error above, instead, you will need to fall back using [OutputCache(Duration = 10, VaryByParam = "id")] on your controller action.

You can download the full code example from GitHub

There is so much more to caching, but I hope you found this brief blog helpful.