Introduction
MVC provides users a way to cache any output (view/data) from any controller for a definite time. This feature can also be used at action level. We will write a quick code to see this, in the following sections.
We will also create some cache profile and will be using them for caching different sections. This will make the caching strategy easy to cater to some extent of changes going further, without fresh deployment.
Let’s dive in to code now.
Lets start with a blank MVC application
Open Visual Studio 2013 IDE, and create a new project as shown below:
Select ASP.NET Web Application:
Select Empty template and check MVC (so that MVC folders are created in code structure). Click on OK, no need to change any other option.
This will give us a blank MVC application where we can add the code required for this demo.
Add the code to see it happening:
Let’s add a Home controller in the controller folder and add the following code in that:
namespace MVCCache.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[OutputCache(Duration = 5)]
public string GetHeaderData()
{
return "Header data is returned at " + DateTime.Now.ToString();
}
[OutputCache(Duration = 10)]
public string GetFooterData()
{
return "Footer data is returned at " + DateTime.Now.ToString();
}
}
}
Here we have three action methods:
- Index – This return index view.
- GetHeaderData – This return header data. For testing our cache code, we have also added date time there. This will tell us at what time this data has been fetched fromthe server. Ideally it should go to server to fetch the data only after the header cache is expired.
If you notice on the top of action method, we have added [OutputCache(Duration = 5)].
This tells the application to cache this data for 5 seconds and for any request for this data before cache is expired fetch the data from cache itself. Once cache is expired it should fetch the data again from the server.
- GetFooterData – This returns footer data. For testing our cache code, we have also added date time there. This will tell us at what time this data has been fetched from server. Ideally it should go to the server to fetch the data only after the footer cache is expired.
If you notice on the top of action method, we have added [OutputCache(Duration = 10)].
This tells the application to cache this data for 10 second and for any request for this data before cache is expired fetch the data from cache itself. Once cache is expired it should fetch the data again from the server.
Now let’s create index view inside Home folder in view and add Head and body section as described below:
Head section code
This section just contais a couple of classes to differentiate header and footer fromthe rest of the data. (it can be replaced with any other style code).
<head>
<meta name="viewport" content="width=device-width" />
<title>Main</title>
<style>
header
{
height: 200px;
background: orange;
text-decoration: solid
}
footer
{
height: 200px;
background: green;
text-decoration: solid
}
</style>
</head>
Body section code
Now here, header section is calling "GetHeaderData" action method and showing whatever is returned from this method. Keep in mind we have cached this data for five seconds.
Footer section is just calling "GetFooterData" action method and showing whatever is returned from this method. Keep in mind we have cached this data for 10 seconds.
In between header and footer, this view also rendering some data on its own, which is not cached at all.
Notice, all these sections are displaying data fetching time at the top of the respective section.
<head>
<meta name="viewport" content="width=device-width" />
<title>Main</title>
<style>
header
{
height: 200px;
background: orange;
text-decoration: solid
}
footer
{
height: 200px;
background: green;
text-decoration: solid
}
</style>
</head>
Test the Application
Test the application
OK, the basic code required for caching is now completed, (cache profile code is remaining, we will discussthat at the end) so let’s test the application we have created.
Now remember, we have cached header for five seconds, footer for 10 seconds, and content is not cached at all. So we should expect the header code to go to the server and get the fresh data every five seconds, and until then if a request comes it should show the data from cache. Similarly footer code should do this for 10 seconds as it is cached for 10 seconds.
The rest of the content is not cached, hence, for every refresh it should go to the server and get fresh data.
Now let’s run the application and see if it behaves as we are expecting. When we run this application it will be showing a page like below:
In summary, what we have done in this code is, we cached two section of our web page for two different time periodsand kept one section live with no caching for that part of the data.
Cache Profiling
The only thing left in this code is to make it a bit more deployable. As of now if we need to change header cache time to 30 seconds from five, we need to change the code base and that will require a deployment. To avoid this we can use cache profiling. It’s nothing but moving the cache duration setting to configuration and giving it a name. This cache profile name can be used instead of defining the duration in controller. Let’s see the code to add cache profiles in the code we have already added above.
In web.config of your project, add caching section inside <system.web> section, as shown below:
Now we have two caching profiles ready, which we can use instead of defining cache properties in controllers.
Let’s change the controller code as mentioned below:
[OutputCache(Duration = 5)] - [OutputCache(CacheProfile = "HeaderCache")]
[OutputCache(Duration = 10)] [OutputCache(CacheProfile = "FooterCache")]
Whenever we want to change the time of cache for header or footer, we can just change the duration in webconfig and get that effected with no deployment needed.