A programmers guide to Caching in ASP.NET

 

The cache object

You can use the System.Web.Caching.Cache object witch is a application wide object for storing data in memory, this object is a Key/Value collection and is used the same way as i.e. the Session object in the way you store data inside it. You can store any type of objects in the Cache as long as the objects can be serializable. When returning values form the cache object always check for the item not to be null, if the item is null then retrieve the data from its original source. Also remember to cast the value to its type when you retrieve the data.

The following is a simple example of storing a DateTime object in the Cache object.

image

Although the previous example is fine you can use the Cache objects Insert method to access much more sophisticated functionality. The following is a list of parameters for the Insert method

key This is the name (string) that you’ll use to access the cached object in the Cache collection.
value The data (object) you want to cache.
dependencies A CacheDependency object identifies a file or a key to another item in the cache. So that a change to a file or related item is changed, the cache will be removed. This is useful for i.e. a file cache, when the file changes the cache is removed.
absoluteExpiration The time (DateTime) at which the object should be removed from the cache.
slidingExpiration The time (TimeSpan) for how long a item will remain in the cache object, i.e. 10 seconds, if a user have not accessed the item in 10 seconds the item is removed, otherwise it will restart the time and add 10 more seconds.
priority

This is a CacheItemPriority enumeration value that you can use to determine which items are removed first when memory starts to run low (scavening). The lowest priority items will be removed first.

  1. Low
  2. BelowNormal
  3. Normal (default)
  4. AboveNormal
  5. High
  6. NotRemovable
onRemoveCallback This is an event handler that is called when the object is removed from the cache, This can be null if you don’t want to specify a callback method.

Now lets do the example form above but this time use the Insert method.

image

The true power of the Insert method comes when you add dependencies to your cached item.

Defining a Cache Dependency

A cache dependency lings a cached item to something else such as a file or another item in the cache collection. ASP.NET then handle the dependencies and removes cached items if the dependent items chances, such as a file change.
This is an example of a Cache object dependent on a file.

Add a text file to your project:

image

In the Page_Load method there is two Cache.Insert one without dependency and one with file dependency.

image

The TextFile.txt just contains the following text:

This is a cached text form a file!

When viewing the page it will look like the following image.

image

The first line comes from the Cache[“FileCache”] item which have no dependency to the file, and the other line is from Cache[“FileCacheDependent”] which does have a specified dependency to the file TextFile.txt. Now what happens when I change the text in the TextFile.txt. This is the result:

image

Notice the second line where it now says: The text has now changed! 
The Cache[“FileCacheDependent”] where automatically removed from the cache because the file changed.

There is also possible to add multiple dependencies for a cached item.
The following example create a new cache named DependentCacheItem that will be removed after 15 seconds if no user access it. Then two System.Web.Caching.CacheDependency objects is created, dep1 and dep2, where the first is a dependency on the file TextFile.txt used earlier, the second is a dependency for the cache item named DependentCacheItem created first. To manage all dependencies you create a object of type System.Web.Caching.AggregateCacheDependency, then add the two CacheDependency objects (dep1 and dep2) by using the AggregateCacheDependency.Add method.

So far we just created the objects for dependencies, after that you create the actual Cache item to use the dependencies, in this example it has the key CacheMultiDependent, Then in the Cache.Insert method specify the key parameter, the value parameter, and the AggregateCacheDependency object. And now the Cache item will be removed after 15 seconds if no user have accessed Cache[“DependendCacheItem”] or the text file TextFile.txt is changed.

image

 

The difference between Absolute Cache Expiration and Sliding Cache Expiration

When create a new cache item you can specify the expiration. In other words how the cache will expire. Two ways of doing so is the use of absolute or sliding expiration. You can use either absolute expiration or sliding expiration or both on the same cache item.

Absolute expiration
Absolute expiration is set as a DateTime object and specify when the cache item will expire.
To set absolute expiration you provide a DateTime object as the forth parameter in the Cache.Insert method.image

The code above shows a absolute expiration cache item. Notice the fifth parameter which is set to System.Web.Caching.Cache.NoSlidingExpiration this is required when not specifying a sliding expiration parameter.

Sliding expiration
Sliding expiration is set as a TimeSpan object and specify for how long the cache item will remain in memory when no user accesses it. When a user accesses the cache item, the time is reset and starts over.

image

It is possible that heavy usage will result in an item never being removed from the cache, preventing updates to the original object from being accessed. This situation can be avoided by specifying a absolute expiration in addition to a sliding expiration.

Using output caching in ASP.NET pages

To set caching on a page in ASP.NET you need to add a @ OutputCache directive to the top of a page’s markup. There are quite a few attributes that can be used to control how the output caching should work in terms of duration and variations of pages. The following table explains the available attributes.

Duration The number of seconds to cache the page. This is the only required parameter.
Location

One of the OutputCacheLocation enumeration values:

  • Any (default)
  • Client
  • Downstream
  • Server
  • None
  • ServerAndClient

This attribute can not be used in user controls (.ASCX files).

CacheProfile The name of the cache setting to associate with the page. You can create one or more CacheProfile in the Web.config file, and make different pages use different CacheProfiles. This attribute can not be used in user controls (.ASCX files).
NoStore A boolean value that determines whether to prevent secondary storage of sensitive information. This attribute can not be used in user controls (.ASCX files).
Shared A boolean value that determines whether user control output can be shared with multiple pages, default is false. This attribute can not be used in ASP.NET pages (.ASPX files).
VaryByParam

A semicolon-sparated list of strings used to vary the output cache. By default, these strings correspnd to a query string value sent with Get method attributes, or a parameter sent by using the Post method. When this attribute is set to multiple parameters, the output cache contains a different version of the requested document for each combination of the specified parameters. Possible values include the following;

  • none
  • *
  • i.e. search (this is a example of the following url, http://example.com?search=test, where the output cache would have a different version for each value in the search query string).
  • i.e search;category (this is a example of the following url, http://example.com?search=test&category, where the output cache would have a different version for each value in the search and category query string).
  • i.e. a ASP.NET-generated control name like, ctl00$MainContent$SearchTextbox, or ctl00$MainContent$CategoryDropDownList.

Either this or VaryByControls is required or a parser error occurs. If you do not want to vary by parameter, then set it to none.

VaryByControl A semicolon-separated list of strings used to vary a user control’s output cache. This strings represent the ID property values of ASP.NET server controls declared in the user control.
SqlDependency A string value that identifies a set of database and table name pairs that a page or control’s output cache depends on. Note that the SqlCacheDependency class monitors the table in a database that the output cache depends on, so that when items in a table are updated, those items are removed from the cache when using table-based polling. When using notifications (in Microsoft SQL Server 2005) with the value CommandNotification, ultimately a SqlDependency class is used to register for query notifications with the SQL Server 2005 server.
VaryByCustom Any text that represents custom output caching requirements. If this attribute is given a value of browser, the cache is varied by browser name and major version information, If a custom string is entered, you must override the GetVaryByCustomString method in you application’s Global.asax file.
VaryByHeader A semicolon.separated list of HTTP header used to vary the output cache. When this attribute is set to multiple headers, the output cache contains a different version of the requested document for each combination of specified headers.

 

To add output caching to a .ASPX page or user control add the @ OutputCache directive in the top of the page.

image

This will cache the page for 15 seconds regardless of the parameters passed to the page.

An alternative way of doing a partial page cache is to use a ASP.NET Control called Substitution, it is like a Label control but you can use it to load dynamic data to a cached page:
image

This control have one important method, MethodName which takes a string representing another method. In this example GetCurrentDateTime.

image

The GetCurrentDateTime is a simple method that takes a HttpContext object as a parameter and returns a string, which is the dynamic data inserted into the cached page.

image

Programmatically set Caching for single pages

To set output caching at runtime you can use the Response.Cache object. This object has limited functionality but can be useful in some situations. The methods that can be used is the following;

  • Response.Cache.SetExpires Use this method to specify a DateTime object that will expire the cache.
  • Response.Cache.SetCacheability Use this method to specify an HttpCacheability enumeration value, please see MSDN for all possibly values.
  • HttpCacheability.Public enables caching at both client and server
  • HttpCacheability.Server enables caching at the server only.
  • Response.Cache.SetValidUntilExpires Pass this method a true value to configure the cache to ignore cache-invalidation headers.
  • Let’s look at how we can invalidate a cached page. The following example shows how to programmatically invalidate a cached page.

    Add the following to your .ASPX page so it will be cached for 15 seconds, on all variations of query strings.

    image

    In the Page.Load event handler we add a new HttpCacheValidateHander to the Response.Cache.AddValidationCallback method. The first parameter of the HttpCacheValidateHander pass a object with your validation method for validation if the cache is valid or not.

    image

    The method to validate a cached page can look however as long as the signature of the method remains the same and the referenced HttpValidationStatus is set to one of the following three;

    • HttpValidationStatus.Invalid the cache is invalid, and the page is dynamically generated, this newly generated page is stored in the cache replacing the earlier cached version.
    • HttpValidationStatus.IgnoreThisRequest This cases the current page request to be dynamically generated without invalidating the  previously cached version of the page. The dynamically generated page output is not cached, and future requests might recive the previously cached output.
    • HttpValidationStatus.Valid Cases ASP.NET to return the cached page.

    image

    You can also programmatically create a cache dependency when using the Response.Cache object. To do so use one of the following methods;

    • Response.AddCacheDependency creates a dependency on a CacheDependency object.
    • Response.AddCacheItemDependency and Response.AddCacheItemDependencies creates a dependency to one or more other items in the cache.
    • Response.AddFileDependency and Response.AddFileDependencies These makes the validity of a cache response dependent on one or more files.

    Configure Caching for en Entire Application

    You can create caching profiles in the Web.config files to control the caching of the entire application from one place. This is a good way to manage many different caching properties for different pages and user controls. In the <system.web> element you can create outputCacheProfiles like the following example.

    image

    Then you can use this caching profiles on different pages.

    image

    Follow

    Get every new post delivered to your Inbox.