Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

ASP.NET Cache

0.00/5 (No votes)
9 Nov 2009 1  
Explains Cache features in ASP.NET

Introduction

Caching is a technique of storing data in memory which takes time to create. Caching is one of the best features of the ASP.NET. For example, you could cache the data from complex query which takes time to fetch data. The subsequent requests would not need to fetch data from the database. You can get data directly from the cache. By using the cache, you can improve the performance of your application.

There are two main types of caching:

  1. Output caching
  2. Data caching

1. Output Caching

By using Output cache, you can cache the final rendered HTML of the page. When the same page is requested again, the cached page is served. ASP.NET does not start the page life cycle and does not execute the code. The syntax of Output cache is:

 <%@ OutputCache Duration=”60” VaryByParam=”None”  %> 

Duration attribute sets that page will be cached for 60 second. If any user requests the page first ASP.NET runs the page code and sends the rendered HTML to user and also saves it to the cache. If server receives a request of the same page within 60 seconds, ASP.NET automatically sends the cached copy page. If Server receives a request after the expiration of cached page, ASP.NET runs page code again and creates a new cached copy of HTML output for next 60 seconds.

 <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"
        CodeFile="OutputCachingTest.aspx.cs" 
	Inherits="OutputCachingTest" Title="Untitled Page" %>

 <%@ OutputCache Duration="20" VaryByParam="None" %>

 <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
 
   <div class="title">Output Cache</div>
   Date: <asp:Label ID="lblDate" runat="server" Text="" />
   Time: <asp:Label ID="lblTime" runat="server" Text="" /> 
      
 </asp:Content>
 protected void Page_Load(object sender, EventArgs e)
 {
    lblDate.Text = DateTime.Now.ToShortDateString();
    lblTime.Text = DateTime.Now.ToLongTimeString(); 
 } 

In this example, page will be cached for 20 seconds.

Cache by Query String

In the real word scenario, Dynamic page changes its contents according to some parameters. If your page is receiving information through query string, you can easily cache different copies of page according to query string. VarByParam=”None” tells ASP.NET to store one copy of the cached page. VarByParam=”*” tells ASP.NET to store a separate copy of the page for different query string parameters.

 <%@ OutputCache Duration="60" VaryByParam="*" %>
 
 <div align="right">
   <a href="OutputCachingTest2.aspx">No Query String</a> | 
   <a href="OutputCachingTest2.aspx?id=1">ID 1</a> | 
   <a href="OutputCachingTest2.aspx?id=2">ID 2</a> | 
   <a href="OutputCachingTest2.aspx?id=3">ID 3</a> |
   <a href="OutputCachingTest2.aspx?id=3&langid=1">ID 3</a>
 </div> 

In the sample project, I am passing a different “ID” in the query string. ASP.NET stores a separate copy for each “ID” and this technique is good in this scenario. But this technique has some problems, if page is accepting wide range of different query strings. In this case, ASP.NET caches separate a copy of page according to query string parameters and potentially lowers the reusability. In this case, you can specify important query string variable names in VarByParam attribute.

 <%@ OutputCache Duration="60" VaryByParam="id;langid" %>

In this case, ASP.NET caches separate version differs by “id” or “langid”.

Custom Caching

You can also create your own custom procedure to cache page. ASP.NET provides a way to create custom cache easily. Use VarByCustom attribute to specify the name that represents the type of custom cache you are creating.

 <%@ OutputCache Duration="20" VaryByParam="None" VaryByCustom="browser" %>

You also need to create a method that will generate a custom string for cache. Syntax of the method is:

 public override string GetVaryByCustomString(HttpContext context, string custom)
 { 
    if (custom == "browser")
    {
       return context.Request.Browser.Browser +
              context.Request.Browser.MajorVersion;
    }
    else
    {
       return base.GetVaryByCustomString(context, custom);
    }
 }

This method must be coded in the global.asax file. This method returns a string value and ASP.NET uses this string to implement caching. If this method return the same string for different requests, ASP.NET reuses the cached page otherwise ASP.NET generates a new cached version.

In our above example, GetVaryByCustomString() creates a cache string based on browser name. ASP.NET will create a different version of cache for different browser requests.

Control Cache

In the above caching technique, you can cache the complete page easily but if you want to cache the contents of specific control, you can achieve this feature by using VaryByControl attribute to cache a control.

 <%@ OutputCache Duration="20" VaryByControl="MyControl_1" %>

By adding this line on .aspx page, ASP.NET will cache MyControl_1 for 20 mins. In this scenario, ASP.NET creates one cached version of the “MyControl_1” and if cache has not expired, ASP.NET reuses the cached version otherwise it executes controls code again.

If you want to cache the control depending on some property value, ASP.NET also provides you this facility. Just add OutPutCache directive in the *.ascx page.

 <%@ Control Language="C#" AutoEventWireup="true" 
	CodeFile="MyControl.ascx.cs" Inherits="Controls_MyControl" %>
 <%@ OutputCache Duration="20" VaryByControl="EmployeeID" %>
 ......
 ...... 

VaryByControl=”EmployeeID” tells ASP.NET to create a different version of the control depending on the EmployeeID property declared in the control.

Add EmplyeeID property in .ascx.cs file which will be used by ASP.NET for cache.

 private int _employeeID;

 public int EmployeeID
 {
   get { return _employeeID; }
   set { _employeeID = value; }
 }

 protected void Page_Load(object sender, EventArgs e)
 {
   lblDate.Text = DateTime.Now.ToShortDateString();
   lblTime.Text = DateTime.Now.ToLongTimeString();

   lblEmployeeID.Text = EmployeeID.ToString();

 }

Add control on the page and set EmployeeID.

 <%@ Register Src="Controls/MyControl.ascx" TagName="MyControl" TagPrefix="uc1" %>
 <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    <div align="center">
        <uc1:MyControl ID="MyControl1" runat="server" EmployeeID="1"></uc1:MyControl>
    </div>
 </asp:Content>

Cache Profile

ASP.NET also provides you a facility to define cache settings in the web.config. Suppose if you embed cache setting into the page and you want to change cache duration from 20 to 30 seconds, then you need to change duration in all pages. It is better to save cache setting in web.config and you can easily manage your cache setting.

<system.web>
  <caching>
    <outputCacheSettings >
      <outputCacheProfiles>
	    <add name ="ProductItemCacheProfile" duration ="60"/>
	  </outputCacheProfiles>
	 </outputCacheSettings>
   </caching>
 </system.web>

Now you can use this profile in page using CacheProfile=”ProfileName” attribute.

 <%@ OutputCache CacheProfile ="ProductItemCacheProfile" VaryByParam="None" %>

2. Data Caching

ASP.NET also provides you a flexible type of caching called data cache. You add items which are expensive to create in a collection object cache. Cache is a key, value pair collection, you can add item into cache collection just by assigning a new key name.

 Cache["Name"] = data;

This technique does not provide control over cache object. Use Cache.Insert() method which provides five versions of methods. By using Insert method, you can set cache expiration policy, Priority, Dependencies, etc.

 date1 = DateTime.Now;
 Cache.Insert("Date1", date1, null, DateTime.Now.AddSeconds(20), TimeSpan.Zero);

ASP.NET allows you to set an absolute expiration or sliding expiration policy, but you can use only one at the same time.

Cache Dependency

You can also set Cache dependency in ASP.NET. Cache Dependencies allow you to make a cached item dependent on another resource, so that when that resource changes, the cached item is removed automatically. CacheDependency class is used for creating dependency. This class has many constructor versions. You can create dependency on file or folder. If that file or folder will change, the cache will be expired. You cache dependency on other cache item.

 date2 = DateTime.Now;

 string[] cacheKeys = { "Date1" };
 CacheDependency cacheDepn = new CacheDependency(null, cacheKeys);
 Cache.Insert("Date2", date2, cacheDepn);

In this example “Date2” cache object depends on the “Date1” cache item. When “Date1” object will expire then “Date2” will automatically expire. In CacheDependency(null, cacheKeys) constructor, the first parameter is 'null' because we are not creating cache having file/folder dependency. We only passed keys list of cached item, because we want to create item cache dependency.

Callback Method and Cache Priority

ASP.NET also allows you to write a callback method that will be triggered when cached item is removed from the cache. You can also set the priority of the cached item.

 protected void Page_Load(object sender, EventArgs e)
 {
   DateTime? date1 = (DateTime?)Cache["Date1"];
   if (!date1.HasValue) // date1 == null
   {
     date1 = DateTime.Now;
     Cache.Insert("Date1", date1, null, DateTime.Now.AddSeconds(20), TimeSpan.Zero, 
                  CacheItemPriority.Default, 
		new CacheItemRemovedCallback(CachedItemRemoveCallBack));
   }

   DateTime? date2 = (DateTime?)Cache["Date2"];
   if (!date2.HasValue) // date2 == null
   {
     date2 = DateTime.Now;
     Cache.Insert("Date2", date2, null, DateTime.Now.AddSeconds(40), TimeSpan.Zero, 
                  CacheItemPriority.Default, 
		new CacheItemRemovedCallback(CachedItemRemoveCallBack));
   }

   // Set values in labels
   lblDate.Text = date1.Value.ToShortDateString();
   lblTime.Text = date1.Value.ToLongTimeString();

   lblDate1.Text = date2.Value.ToShortDateString();
   lblTime1.Text = date2.Value.ToLongTimeString();

 }
    
 private void CachedItemRemoveCallBack(string key, object value, 
				CacheItemRemovedReason reason)
 {
   if (key == "Date1" || key == "Date2")
   { 
      Cache.Remove("Date1");
      Cache.Remove("Date2");
   }
 }

As you can see in the example, I created “Date1” & “Date2” cache. “Date1” expiry Duration is 20 seconds and “Date2” has 40 seconds but you will notice that both expire together. The reason is because we have registered remove callback method. When “Date1” or “Date2” expires, it calls CachedItemRemoveCallBack method. In this method, I remove both the cached items.

ASP.NET also provides you a facility to handle update callback handler for cached item. CacheItemUpdateCallback delegate event uses for this purpose.

References

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here