Click here to Skip to main content
Click here to Skip to main content

A Beginner's Tutorial for Understanding and Implementing Caching in ASP.NET MVC

, 10 Apr 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
In this article we will see how we can implement caching in an ASP.NET MVC application

Introduction

In this article we will see how we can implement caching in an ASP.NET MVC application.

Background

As ASP.NET web developers, we are mostly involved in developing web pages that are dynamic, i.e. contents coming from databases, Server directories, XML files or getting pulled from some other websites. Caching means to store something in memory that is being used frequently to provide better performance.

Why should we even care about caching. Let us imagine a scenario when the contents of a web page are being pulled from a database. The user asks for contents depending on some criteria. Now if the database is getting changed very frequently that even between two requests of same user, we anticipate database change, then we can in no way cache the data that the user is requesting. But if the database is not getting changed that frequently, we can have some caching in place so that if the user is requesting the same data very frequently, we don't hit the database every time (since we know contents are not changed).

The two keys terms here are frequency and criteria. Frequency is the number of times we are anticipating the user requests for a particular page and criteria is what governs the uniqueness of result that is being displayed on the page.

Frequency is important because we need to figure out the interval in which database is changing and compare it with the frequency of user requests so that we can have caching in place and also make sure that user is not viewing outdated data.

Criteria is important because we need to make sure that we have caching implemented for the page on every unique criteria. It should not be the case that user is requesting contents based on criteria01 and we are showing him the cached results of criteria00 (cached earlier for him).

So with all this theory in mind, let's go ahead and see how we can implement caching in ASP.NET MVC

Note: I have written a similar article in caching in ASP.NET Web forms. This article talks specifically about caching in ASP.NET MVC. Since the theoretical concept behind caching is same for both the technologies, I have borrowed some of the contents from that article. That article can be found here: A Beginner's Tutorial on Caching in ASP.NET[^]

Using the code

Types of Caching

There are two types of caching available in ASP.NET:

  1. Page Output Caching
  2. Application Caching

Page Output Caching

Page output caching refer to the ability of the web server to cache a certain webpage after user request in its memory so that further requests for the same page will check for the cached page's validity and will not result in resource usage (DB access or file access) and the page will be returned to user from cache.

Let us develop a small application that will demonstrate how we can implement page output caching in ASP.NET MVC. Lets implement a simple view that will show the current time to the user. The Controller code is simply returning the view.

public class TestController : Controller
{
    public ActionResult Index()
    {
        return View();
    }      
}

In my view, I am showing the current time to the user.

@{
    ViewBag.Title = "Caching Demo";
}

Time is @DateTime.Now.ToString()

If we run this application now, it will show me the current date and time. If we refresh it, the time also gets updated(since there is no caching implemented right now).

Now lets say that this page should be cached for 30 seconds i.e. the time string should not change for 30 seconds. We can wchieve this by adorning the action method with the OutputCache attribute. We will pass 2 values in the attribute, First is the Duration of cache and second property VaryByParam. VaryByParam="none" specifies that caching doesn't depend on anything.

public class TestController : Controller
{
    [OutputCache(Duration=30, VaryByParam="none")]
    public ActionResult Index()
    {
        return View();
    }      
}

Now if we run the page and refresh it, the time will not change for 30 seconds.

In the above example, we have specified VaryByParam="none". Doing so can lead to a situation where user might see stale data. So if we want to invalidate the cache based on some user selection in screen, then we can specify the VaryByParam's value. So If I want to cache different values for page requests having different query string, I can specify the varyByParam value as the name of that query string.(or any HTML element I want to use).

public class TestController : Controller
{
    [OutputCache(Duration = 30, VaryByParam = "none")]
    public ActionResult Index()
    {
        return View();
    }

    [OutputCache(Duration = 30, VaryByParam = "id")]
    public ActionResult Index1()
    {
        return View();
    }
}

So now if I run the application and navigate to Index1, I will see a cached version for each value of "id" query string.

So what we saw is that we can specify the Duration the page should be cached which is related to the talk about frequency we did earlier. The Duration should be chosen so that during that time we are not expecting any change in data and for the criteria, we saw how we can use VaryByParam to make sure that the output for every different criteria is generated and the cached copy is not just presented to the user.

If we need different output pages based on any/all of the HTML element change, we can specify the list of VaryByParam ="*". Let us look as some other parameters that we can use to customize caching behavior.

  • VaryByParam: List of strings that are sent to server via HTTP POST/GET that are checked to validate cache
  • VaryByCustom: Used for custom output cache requirements
  • VaryByHeader: HTTPs header that determines the cache validity
  • SqlDependency: Defines the Database-tablename pair on which the validity of cache depends

Cache Location

There is one more important property of the OutputCache attribute class which is Location. This property will determine where will the cached data be stored on the server. Possible values for this property can be:

  • Any (Default): Content is cached in three locations: the web server, any proxy servers, and the web browser.
  • Client: Content is cached on the web browser.
  • Server: Content is cached on the web server.
  • ServerAndClient: Content is cached on the web server and and the web browser.
  • None: Content is not cached anywhere.

Smarter ways to specify Cache attribute

If all our action methods have same caching needs then instead of adorning all the individual action methods with this attribute, we can simply go and adorn the controller with this attribute and the caching will be effective on all the aciton methods.

[OutputCache(Duration = 30, VaryByParam = "none")]
public class TestController : Controller
{   
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Index1()
    {
        return View();
    }
}

In case we have multiple action methods across controllers needing the same caching behavior, we can put this caching values in the web.config and create a cacheprofile for it.

<caching>
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name="MyCacheProfile"
               duration="30"
               varyByParam="id"
               location="Any" />
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>

And to use these values in the action methods we just need to specify the CacheProfile name in the action method.

[OutputCache(CacheProfile = "MyCacheProfile")]
public ActionResult Dummy()
{  
    return View();
}

Partial Page Caching

In asp.net Web forms, we need to create custom user controls in order to achieve partial page caching. Same can be achieved in the MVC world by creating a simple partial view. Caching in that partial view will be governed by the OutputCache attribute associated with the action method responsible to render the data in this partial view.

To Illustrate this let us create one more action method Index2 in the controller. This action will not cache the data. We will render a partial View in this Index2 View. The partial view will cache the time for 10 seconds. Lets look at the action methods for these.

public ActionResult Index2()
{
    return View();
}

[OutputCache(Duration = 10, VaryByParam = "none")]
public PartialViewResult PartialTest()
{
    return PartialView("SamplePartial");
}

The Index2 View looks like:

@{
    ViewBag.Title = "Caching Demo";
}

Time is @DateTime.Now.ToString()

<br /><br />
Partial page here: @Html.Action("PartialTest")

And finally the partial view code:

Time: @DateTime.Now.ToString()

Now if we run the application and navigate to Index2, we can see that the time from the main page is not getting cached but the the time coming from the partial view is getting cached for 10 seconds.

Application Caching

Application data caching is a mechanism for storing the Data objects on cache. It has nothing to do with the page caching. ASP.NET allows us to store the object in a Key-Value based cache. We can use this to store the data that need to cached. Let us work on the same example and try to store the DateTime string in the Application Cache now.

Let us create one action method which will display the date on the view from the application cache.

public ActionResult Index3()
{
    if (System.Web.HttpContext.Current.Cache["time"] == null)
    {
        System.Web.HttpContext.Current.Cache["time"] = DateTime.Now;
    }

    ViewBag.Time = ((DateTime)System.Web.HttpContext.Current.Cache["time"]).ToString();
    return View();
}

The view corresponding to this action method is:

@{
    ViewBag.Title = "Caching Demo";
}

Time is @ViewBag.Time

Now if we run the application and navigate to Index3, we will see the time. But no matter how many times, we refresh this page, the time value will not change. Because the value is coming from the Application cache. Also, we are not invalidating the cache at all.

There are various parameters associated with application data caching that can be used to invalidate the value and control its behavior.

  • Dependencies: Any file or item in cache that invalidates this cache item
  • absoluteExpiration: Absolute time when this object should be removed from cache
  • slidingExpiration: Relative time when this object should be removed from the cache
  • priority: Defines the priority of the item. This is useful when server runs out of memory as in that case it start removing items from cache with lowest priority first
  • onRemoveCallBack: This is the event handler that will be called when the object is removed from cache. It gives us a place to take further actions.

Point of interest

in this article, we saw how we can implement caching in an ASP.NET application. The sample solution contains a complete working sample for the discussed topics. Nuget packge restore is enabled for this solution so the application will download the dependent packages before building. This article has been written from a beginner's perspective. I hope this has been informative.

History

  • 09 April 2014: First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Rahul Rajat Singh
Software Developer (Senior)
India India
I Started my Programming career with C++. Later got a chance to develop Windows Form applications using C#. Currently using C#, ASP.NET & ASP.NET MVC to create Information Systems, e-commerce/e-governance Portals and Data driven websites.

My interests involves Programming, Website development and Learning/Teaching subjects related to Computer Science/Information Systems. IMO, C# is the best programming language and I love working with C# and other Microsoft Technologies.
  • Microsoft Certified Technology Specialist (MCTS): Web Applications Development with Microsoft .NET Framework 4
  • Microsoft Certified Technology Specialist (MCTS): Accessing Data with Microsoft .NET Framework 4
  • Microsoft Certified Technology Specialist (MCTS): Windows Communication Foundation Development with Microsoft .NET Framework 4
 
If you like my articles, please visit my website for more: www.rahulrajatsingh.com[^]
Follow on   Twitter   Google+   LinkedIn

Comments and Discussions

 
GeneralMy vote of 5 PinmemberM Rayhan27-Nov-14 19:44 
GeneralMy vote of 5 PinprofessionalAssil27-Oct-14 5:06 
Questioncahe-sqldependency PinmemberMember 95079781-Oct-14 0:37 
GeneralVery Helpful Article Pinmemberarvind mepani9-Jul-14 3:01 
AnswerArticle of the Day on Microsoft's site PinmvpRahul Rajat Singh8-Jul-14 19:42 
Questiongreat article PinprofessionalMember 1035419727-May-14 5:29 
GeneralMy vote of 5 PinprofessionalRenju Vinod14-May-14 22:27 
GeneralMy vote of 5 PinmemberHumayun Kabir Mamun21-Apr-14 23:54 
GeneralNice one PinmemberSundar Babu14-Apr-14 22:04 
QuestionNice One PinprofessionalRahul VB13-Apr-14 18:45 
AnswerRe: Nice One PinmemberSundar Babu14-Apr-14 22:07 
GeneralRe: Nice One PinprofessionalRahul VB15-Apr-14 0:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141220.1 | Last Updated 10 Apr 2014
Article Copyright 2014 by Rahul Rajat Singh
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid