Tactical Advice

Server-side Output Caching

Using output caching to improve the performance of your ASP.NET Web application.
This story appears in the March 2007 issue of BizTech Magazine.

Here’s an easy way to dramatically improve performance and scalability of your ASP.NET Web applications: enable output caching. It takes less than one minute to enable caching on pages that aren’t personalized for individual users, such as news listings, search results and product catalogs. If your content is personalized or extremely time sensitive, you can significantly reduce ASP.NET rendering time with just a couple of hours of work.

Even the most dynamic sites can benefit from caching, through these techniques:

  • page caching, which caches an entire rendered ASP.NET page;
  • adding user control caching and write substitution, which cache portions of a page;
  • discarding cached results when a database is updated;
  • programmatically determining whether to use a cached page or rerender the ASP.NET page.

Server-side output caching is a quick and easy way to increase your Web application’s performance and scalability. Implementing caching in a typical Web application that includes some dynamic content can reduce processor utilization by 90 percent across all tiers of an application, including the front-end Web server, application servers and database servers. Because you control which portions of a page are cached and when the cache is updated, you can cache personalized pages and pages that display database queries without worrying about ever serving stale data. Maybe management could take some of the budget that they save on server upgrades and give the developers a raise!

How to Enable Page Caching

With ASP.NET 2.0, you can enable server-side page output caching to store a copy of pages after ASP.NET has rendered them. If the same or a different user requests the page, ASP.NET serves the cached copy about as fast as it would serve static HTML because ASP.NET completely bypasses the rendering process.

To enable server-side page output caching, add the following directive to the top of your .aspx page:

<%@ OutputCache Duration="15" VaryByParam="none" %>

Notice that this example of the OutputCache directive includes the two required parameters:

  • Duration: The length of time, in minutes, ASP.NET will use the cached output before rerendering the page.
  • VaryByParam: A list of query parameters that, if the values are different, should be cached separately as if it were a different Web page.

Let’s say you have an ASP.NET page to browse your inventory by category, and a typical URL looks like this:

http://server/browse.aspx?category=widgets&page=1

Obviously, you wouldn’t want the output for the “widgets” category to be returned for the “gadgets” category, and each page number would have unique results, so you would use the following directive at the top of the browse.aspx page:

<%@ OutputCache Duration="15" VaryByParam="category; page" %>

This directive would cause ASP.NET to cache both pages 1 and 2 of the “widgets“ category separately, and rerender the page after 15 minutes. The “gadgets” and “widgets” categories would be cached separately, too. To create a separate cache for every parameter, set VaryByParam to “*”.

How to Cache Portions of a Page

Many pages are personalized to show the user’s name, customized stock quotes or local ads. The directive described in the previous section would also cache personalized content, and cause it to be sent to the wrong users. To work around this, move any personalized content into .ascx user controls and add the “@ OutputCache” directive to the user controls (even if you simply need to disable caching for that control). ASP.NET will cache the user controls separately from the parent page and combine the cached output for every page that needs to be rendered. To disable output caching for a control, add the following directive to the top of the .ascx page:

<%@ OutputCache Duration="0" VaryByParam="none" %>

Instead of creating separate user controls for dynamic content, you may use substitution to dynamically generate HTML for parts of a page. To use substitution, follow these steps:

  1. Create a callback method that accepts an HttpContext object and returns a string containing the HTML content, as the following example demonstrates:

    ‘VB
    Shared Function GetDate (ByVal context As HttpContext) As String
        return DateTime.Now.ToString()
    End Function

    //C#
    Public Static String GetDate (HttpContext context)
    {
        return DateTime.Now.ToString();
    }

  2. Use the designer to add a Substitution control to your .aspx page.
  3. In the designer, set the Substitution.MethodName property to the name of the method you created in step 1. To run the previous example, you would set Substitution.MethodName to "GetDate."

ASP.NET will automatically run the method you specify for the Substitution.MethodName parameter each time the page is requested, even if it uses the cached output for the rest of the page.

Creating an SQL Server Database Dependency

Thinking back to the example of using page output caching when browsing inventory by category, you might be able to tolerate new products not immediately appearing in cached pages, but you don’t have to. If you use Microsoft SQL Server 2005 on the back end, you may create a Structured Query Language database dependency that automatically invalidates the cache by setting OutputCache’s SqlDependency parameter to the value CommandNotification,  demonstrated as follows:

<%@ OutputCache SqlDependency="CommandNotification" Duration="15" VaryByparam="none" %>

SQL Server 2005 will automatically notify ASP.NET if the results of any queries used in the page have changed, and ASP.NET will rerender the cached page on the next request. For information about how to create queries that support query notification, read “Creating a Query for Notification” at http://msdn2.microsoft.com/en-US/library/ms181122.aspx. If any of your queries don’t support notification (for example, if you used “SELECT *”), no caching will occur.

If you use Microsoft SQL Server 7.0 or Microsoft SQL Server 2000, you may achieve similar functionality by configuring the database using the Aspnet_RegSql.exe command (in your “%windir%\Microsoft.NET\Framework\<build>\” folder) to set up the database and table to support dependencies. For more information, read “Improved Caching in ASP.NET 2.0” at http://msdn2.microsoft.com/en-us/library/ms379559(VS.80).aspx.

Deciding Whether to Use a Cached Page

If you would rather run code to determine whether to use the cached version of a page or rerender it, you may create an HttpCacheValidateHandler for the cached page and set the HttpValidationStatus parameter to one of the following three values:

  • HttpValidationStatus.Invalid: Remove the cache and dynamically generate the page.
  • HttpValidationStatus.IgnoreThisRequest: Dynamically generate the page without overwriting the cache.
  • HttpValidationStatus.Valid: Return the current cache without dynamically generating the page.

The following code demonstrates how to handle the event:

‘VB
Public Shared Sub ValidateCache (ByVal context As HttpContext, _
        ByVal data As [Object], ByRef status As HttpValidationStatus)
    ‘ TODO: Add logic to set one of the following values
    status = HttpValidationStatus.Invalid
    status = HttpValidationStatus.IgnoreThisRequest
    status = HttpValidationStatus.Valid

//C#
public static void ValidateCache (HttpContext context,
        Object data, ref HttpValidationStatus status)
{
    // TODO: Add logic to set one of the following values
    status = HttpValidationStatus.Invalid
    status = HttpValidationStatus.IgnoreThisRequest
    status = HttpValidationStatus.Valid
}

After creating the method, define it as the event handler in the Page_Load method:

‘VB
Protected Sub Page_Load (ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles Me.Load

    Response.Cache.AddValidationCallback ( _
        New HttpCacheValidateHandler (AddressOf ValidateCache), Nothing)

//C#
protected void Page_Load (object sender, EventArgs e)
{
    Response.Cache.AddValidationCallback (
        new HttpCacheValidateHandler (ValidateCache), null);
}

Tony Northrup, Microsoft MVP, MCSE, MCTS and CISSP, is a Windows consultant and author residing in Massachusetts. He has written more than a dozen books covering Windows networking, security and development.
Sign up for our e-newsletter

About the Author

Tony Northrup

Tony Northrup

Tony Northrup is a developer, security consultant and author with more than 10 years of professional experience developing applications for Microsoft Windows.

Security

Review: Belkin Advanced Secu... |
This tool can prevent KVM toggling from being a source of network vulnerabilities.
Honeywords: Password Securit... |
Researchers are proposing a new method of spiking the password punch as a way to identify...
How Many Vulnerabilities Doe... |
The potential for damaging data breaches lurks in nearly every corner for SMBs.

Storage

EMC World 2013: Software-Def... |
Storage virtualization is a key element of providing on-demand, flexible cloud services.
How Steve Wozniak Explains V... |
Fusion-io's chief scientist breaks virtualization down into terms everyone can understand.
Product Review: Quantum NDX-... |
Device does double duty for storage and backup.

Infrastructure Optimization

Why More Software Is Headed... |
Many of your favorite software suites are trading in their shiny discs for cloud-based...
Cisco Live 2013: Brush Up wi... |
Get up to speed on convergence, wireless networking, collaboration and more ahead of the...
EMC World 2013: Software-Def... |
Storage virtualization is a key element of providing on-demand, flexible cloud services.

Networking

How to Secure Optimized Netw... |
WAN optimization and security aren’t always complementary. These tips can help you deal...
Cisco Live 2013: Brush Up wi... |
Get up to speed on convergence, wireless networking, collaboration and more ahead of the...
Do Virtual Meetings Boost Pr... |
New study finds that face-to-face meetings don’t always work in workers’ favor.

Mobile & Wireless

Consumr App Powers Informed... |
Reviews and ratings for products on the shelf are only a barcode scan away.
Faster In-Flight Wi-Fi: Com... |
The FCC is working on regulation to free up more Internet bandwidth for air travelers.
CTIA: Wireless Network Data... |
The invisible bytes that zip through the air continue to multiply at rapid rates.

Hardware & Software

Consumr App Powers Informed... |
Reviews and ratings for products on the shelf are only a barcode scan away.
Review: Belkin Advanced Secu... |
This tool can prevent KVM toggling from being a source of network vulnerabilities.
How Many Vulnerabilities Doe... |
The potential for damaging data breaches lurks in nearly every corner for SMBs.