Data Caching And Page Caching In ASP.NET

Introduction

Caching is a mechanism used by web applications to enhance their performance. Today, web applications are developed at an enterprise level. Such applications use caching to keep the response time to a minimum.

Some of the problems encountered by web applications as well as their corresponding solutions, which are provided by caching, are listed below:

Performance

Web applications store static data such as names of countries, a list of years, and a list of months. Usually, every time the page is requested, this data is retrieved from the database and displayed on the page. Therefore, every user accessing such a page will find that the page takes a few seconds to load.

Caching allows you to store static data in a data store close to the data consumer. For example, it allows you to store such static data either on the client requesting the page, the server hosting the page, or on a proxy server. A proxy server in this case is an HTTP1.1 cache-capable device other than the original server. This reduces the time required to retrieve the data from the database, and recreate the page for every request.

Scalability

Web applications display the same data very often. For example, consider a web application displaying the daily horoscope. Several users will visit the page. Without caching, the web application will generate the requested page and render it for every request. This involves the repetitive rendering of the same information. Caching allows you to store rendered pages in an output cache and reuse them for every subsequent request. Therefore, even if the number of users increases, the web application has to just make the cached page available.

Availability

Web applications are usually data retrieved from a database server. The database could be located on a remote system. If a network failure occurs between the web server and the database server, the web application will be unable to service user requests. Web applications that use caching retrieve the data from the database and then store it in the cache. For subsequent requests, the data is fetched from the cache. Therefore, even if the database server is inaccessible, the web application can still service requests to display data, using the cache. However, note that to refresh the cache, the web application will have to connect to the database server.

Thus caching improves the performance of a web application through the following,

  • The reduced data processing is required in rendering raw data retrieved from the database.
  • Reduced number of disk access operations as most of the cached data is stored in memory.

ASP.NET supports caching of data as well web pages. Applications Data caching enables caching of data whereas Page Output Caching enables Web pages.

Application of Data Caching

In application Data Caching, the web application caches data such as a DataSet instance, DataTable instance, or static data such as names of countries. Such data is stored in an application cache. Every web application is provided with its own copy of the application cache. The application cache is created and maintained through the Cache class. A data item is added to the application cache using the Add() method of the Cache class.

Syntax

public Object Add(string key, Object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemovedCallback)

Where,

  • key is the name that will be associated with the value.
  • value represents the item value.
  • dependencies represent an instance on which the cache item will be dependent for refreshing itself.
  • absoluteExpiration is the time at which the item in the cache expires and is removed from the cache; it can be disabled using the field Cache. NoAbsoluteExpiration
  • slidingExpiration is the time interval between the time the item was last accessed and the time at which the item expires; it can be disabled using the field Cache.NoSlidingExpiration
  • priority is the priority of the item; items with lower priority are removed first
  • onRemovedCallback is the delegate that is called when an item is removed from the application cache.

Code shows the code to add a typed DataTable instance named dtState to the application cache.

DataSet1 dsetState = new DataSet1();
DataSet1TableAdapters.StateTableAdapter taState = new DataSet1TableAdapters.StateTableAdapter();
DataSet1.StateDataTable dtState = dsetState.State;
taState.Fill(dtState);
if (Cache[“StateDataTable”] == null) {
    Cache.Add(“StateDataTable”, dtState, null, DateTime.Now.AddSeconds(60), TimeSpan.Zero, CacheItemPriority.Default, null);
}

The dataset, dsetState, used in this code is a typed dataset used to hold data from a database named YellowPages. The typed TableAdapter instance taState is used to fill the typed DataTable named dtState with records form the State table. The DataTable,dtState is added to the cache using the Add() method. Note that the arguments for CacheDependency and CacheItemRemovedCallback are set to null. Therefore, the Add() method will cache the instance, dtState , with the name StateDataTable for a period of 60 seconds from the current time. The item, StateDataTable is cached with a default priority. The table shows the lists of the various values of the CacheItemPriority enumeration.

Members Description
AboveNormal When freeing the system memory of a cache-capable system, cache items with this priority are less likely to be removed from the cache as compared to items with Normal priority.
BelowNormal When freeing the system memory of a cache-capable system, cache items with this priority are more likely to be removed as compared to items with Normal priority.
Default Cache items are assigned this priority by default.
High When freeing the system memory of a cache-capable system, cache items with this priority will be the last ones selected for removal from the cache.
Low When freeing the system memory of a cache-capable system, cache items with this priority will be the first ones selected for removal from the cache.
Normal When freeing the system memory of a cache-capable system, cache items with this priority are removed once the cache items with Low and BelowNormal Priority have been removed.
NotRemovable When freeing the system memory of a cache-capable system, cache items with this priority are not removed.

Page Output Caching

ASP.NET provides caching of web pages through Page Output Caching. A page is enabled for caching using the @OutputCache directive. This directive is written at the top of the page which is to be cached. The code below shows the code in the hold to cache a web page for 60 seconds.

<%@ Page Language=”C#” AutoEventWireup=”true”  CodeFile=”Default.aspx.cs”
Inherits=”_Default” %>
<%@ OutputCache Duration=”60” VaryByParam=”None” %>
<form id=”form1” runat=”server”>
    <div> Time in cached page:
        <asp:Label ID=”lblTime” runat=”Server”></asp:Label>
    </div>
</form>

The Web page in the given code uses a Label control named lblTime to display the current time. The Text property of this control is set in the Page_Load event handler as shown below,

Protected void Page_Load(object sender, EventArgs e) {
    lblTime.Text = DateTime.Now.ToLongTimeString();
}

Since the page is cached, the same time is displayed each time the page is accessed within the next 60 seconds. After 60 seconds have elapsed if the page is accessed. The time displayed is a new time. Initially, the page was cached for 60 seconds. Therefore, after 60 seconds elapse, the page is removed from the cache. Now, when the page is accessed again, the page is loaded with the current time and then added to the cache for a period of 60 seconds once more.

This type of caching is useful when an entire page is to be cached. For example, News websites have several pages of static data. Therefore, web pages containing news stories can be cached and displayed from the cache for subsequent requests.

Post-Substitution Caching

Consider the scenario of a News Website. The home page of a News Website could display news clippings along with the current date and time, stock prices, game scores, advertisements, and so on. To keep the response time of the website to a minimum, the website requires the entire page to be cached. However, certain sections of the web page that display dynamic data such as advertisements are not to be cached.

Post- Cache substitution allows a web page to have fragments that can be exempted from caching. Post Cache substitution is implemented using substitution API or the Substitution control.

Post-Cache Substitution using Substitution control requires the following,

Static Method

The static method is used to return the dynamic content. The code below shows a static method to return the current time.

public static String GetTime(HttpContext context) {
    return DateTime.Now.ToLongTimeString();
}

The GetTime() method returns the current system time. Note that the static method must return a String and accept a parameter of type HttpContext. This method must be defined in the .aspx file of the Web page or in the code-behind file of the Web page.

Substitution Control

A substitution control is created by dragging it from the toolbox and dropping it on the web form. This control is placed at the location where dynamic content is to be displayed. Next, the control is associated with the static method GetTime() using the MethodName property. At runtime, the Substitution control is replaced with the string returned by the static method GetTime().

The following code shows the modified version of the above code.

<%@ page language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>
<%@ OuputCache Duration=”60” VaryByParam=”None” %>
<form id=”form1” runat=”server”>
<div>

Time in the cached page,

<asp:Label ID=”lblTime” runat=”server”></asp:Label>
<br />
<br />

Time in substitution control,

<asp:Substitution  ID=”sbsTime” runat=”server” MethodName=”GetTime” />
</div>
</form>

Note that the MethodName attribute is set to GetTime. The web page displays two-time values, both of which are the same. When the same page is accessed after 25 seconds, then note that the time value displayed in the cached page is not updated as the cache duration of the page is set to 60 seconds. However, the time value in Substitution control, sbsTime is updated to reflect the system time after 25 seconds. This is because the Substitution control was not cached.

Post-Cache Substitution can also be implemented using the Substitution API. The Substitution API uses the Response.WriteSubstitution() method instead of the Substitution control. The code below shows the usage of the Substitution API in bold.

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”Default” %>
<%@ OutputCache Duration=”60” VaryByParam=”None” %>
<form id=”form1” runat=”server”>
<div> Time in cached page: 
<asp:Label ID=”lblTime”  runat=”server”></asp:Label>
<br />
<br />

Time in Substitution Control,

<% Response.WriteSubstitution(new HttpResponseSubstitutionCallback(GetTime)); %>
</div>
</form>

The Response.WriteSubstitution() method can be used in the code behind the web page as well. A call to the Response.WriteSubstitution() method causes the client-side cacheability to be changed to server cacheability. This means that the page will not be cached on the client. The WriteSubstitution() method accepts an instance of the HttpResponseSubstitutionCallback delegate. A method, a user control, or an object can be passed to this delegate in order to substitute the dynamic item or section in the cached page. In the above code, the name of the static method GetTime() is passed to the delegate, which in turn returns the dynamic content that will be inserted into the page. In this case, it will return the current system time as a String.

When the page is requested for the first time, the WriteSubstitution() method calls the HttpResponseSubstitutionCallback delegate to generate the dynamic content. Next, a substitution buffer is added to the response. This buffer stores the delegate so that future requests can reuse it. Next, the cacheability of the page is changed from public to server. This ensures that future requests to the page invoke the delegate.

Cache Configuration

The cache settings applied in Page Output Caching are applicable only for a particular Web page. However, at times you will have situations where you want to apply the same cache settings to multiple pages. ASP.NET uses Web.config file to specify such configuration information. The benefit of configuring cache through configuration files is that any changes that have to be made, are made in a single central location. Also, the configuration information specified in configuration files can be applied to several pages or an entire Web application. The Web.config file contains two elements, namely <outputCacheSettings> and <outputCache>, to configure page output caching.

<outputCacheSettings> Element

 The <outputCacheSettings> element is used to specify cache settings for one or more pages in a Web application. This is useful, for example, when you want to cache a certain number of pages for 60 minutes and another set of pages for 30 minutes. This is achieved by creating cache profiles in the Web.config file. The <outputCacheProfile> element allows you to specify one or more cache profiles. The code below shows how to create the cache profiles.

<configuration>
  <system.web>
    <caching>
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name=”Cache60Mins” duration=”3600” enabled=”true” />
          <add name=”Cache30Mins” duration=”1800” />
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>
  </system.web>
</configuration>

Note that the <outputCacheProfiles> element is enclosed within the <outputCacheSettings> element which in turn is enclosed inside the <caching> element. The cache profile is created using the <add> element. The first <add> element creates a cache profile named Cache60Mins to cache pages for 6o minutes. The second <add> element creates a cache profile named Cache30Mins to cache pages for 30 minutes. Note that the enabled attribute of <add> element is optional and its true value indicates that output cache is enabled.

After the cache profiles are defined in the Web.config file, they can be referenced in the Web pages using the @outputCache directive. The code below shows the code to associate a cache profile with a web page.

<%@ OuputCache CacheProfile=”Cache60Mins” VaryByParam=”None” %>

The @OutputCache directive uses the cache profile name Cache60Mins to cache a web page for 60 minutes. Note that along with the CacheProfile attribute, the VaryByParam or VaryByControl attribute is mandatory, as shown in the code above. All the attributes that can be used with the @OutputCache directive can be specified as attributes of the <add> element of <outputCacheProfiles> element.

<outputCache> Element

The <outputCache> element is used to configure the Page output Caching of a Web application. This element does not require any child element. All the configuration information about Page Output Caching is specified using attributes. Various attributed of the <outputCache> element are.

enableOutputCache

If set to true, it enabled the page output cache for the Web application. The default value is true.

enableFragmentCache

If set to true, it enables the fragment cache for the web application, Default value is false.

sendCacheControlHeader

If the cache-control private header is sent by the output cache module by default, this attribute returns a Boolean value. The default value is false.

omitVaryStar

If set to true, it enables sending an HTTP “vary:*” header. The default value is false.

The code below shows the code to disable Output Page Caching for a Web application. If individual pages in the Web application use caching declaratively or programmatically, this code will disable caching for that page as well.

<caching>
    <outputCache enableOutputCache=”False” />
</caching>

Summary

Caching improves the response time for a web application by storing data in a cache. Application Data Caching enables caching of application data such as Datasets, DataTable objects, and so on. The Add() method of the Cache class is used to add an item to the application cache. Page Output caching enables caching of individual web pages. Post-Cache Substitution exempts fragments of a web page from caching. With cache profiles, cache settings can be specified for a group of web pages. The <ouputCache> and <outputCacheSettings> elements in Web.Config files are used to configure cache settings in Page Output Caching.