Caching Portions of an ASP.NET Page

Sometimes it is impractical to cache an entire page because portions of the page might need to change on each request. In those cases, you can cache just a portion of a page. There are two options to do this: control caching and post-cache substitution.

In control caching, also known as fragment caching, you can cache parts of the page output by creating user controls to contain the cached content and then marking the user controls as cacheable. This allows specific content within a page to be cached, while the overall page is recreated each time. For example, if you create a page that displays largely dynamic content, such as stock information, but also has sections that are static, such as weekly summaries, you can create the static sections in user controls and configure the user controls to be cached.

Post-cache substitution is the opposite. The page is cached, but fragments within the page are dynamic and should therefore not be cached. For example, if you create a page that is entirely static for set periods of time such as a page of news stories, you can set the entire page to be cached. If you added rotating ad banners to the cached page, they would not change between page requests. However, with post-cache substitution, the page can be cached, but you can mark specific parts as non-cacheable. In the example, you would mark your ad banners as non-cacheable. They would then be dynamically created for each page request and added to the cached page output. For more information on post-cache substitution, see Dynamically Updating Portions of a Cached Page.

Control Caching

Creating user controls to cache content allows you to separate portions of a page that take valuable processor time to create, such as database queries, from other parts of the page. The parts of the page that require fewer server resources can be generated dynamically for each request.

Once you identify the portions of the page that you want to cache and create the user controls that contain each of those portions, you must determine the caching policies for the user controls. You can set these policies declaratively using the @ OutputCache directive, or by using the PartialCachingAttribute class in the code for the user control.

For example, if you include the following directive at the top of a user control file (.ascx file), a version of the control is stored in the output cache for 120 seconds.

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

If you want to set caching parameters in code, you can use an attribute in the user control's class declaration. For example, if you include the following attribute in the metadata of your class declaration, a version of the content in the output cache is stored for 120 seconds:

[PartialCaching(120)]
public partial class CachedControl : System.Web.UI.UserControl
{
    // Class Code
}
<PartialCaching(120)> _
Partial Class CachedControl
    Inherits System.Web.UI.UserControl
    ' Class Code
End Class

For more information on the attributes that you can set on page output, see the @ OutputCache topic. For more information on how to develop user controls, see ASP.NET Web Server Controls Overview.

Note

Because you can nest user controls on a page, you can also nest user controls that have been placed in the output cache. You can specify different cache settings for the page and for nested user controls.

Referencing Cached User Controls Programmatically

When creating a cacheable user control declaratively, you can include an ID attribute in order to programmatically reference that instance of the user control. However, before referencing the user control in code, you must verify the existence of the user control in the output cache. A user control that is cached is dynamically generated only for the first request; any subsequent requests are satisfied from the output cache until the specified time expires. After you determine that the user control has been instantiated, you can programmatically manipulate the user control from the containing page. For example, if you declaratively assign a user control an ID of SampleUserControl, you can check for its existence with the following code:

protected void Page_Load(object sender, EventArgs e)
{
    if (SampleUserControl != null)
       // Place code manipulating SampleUserControl here.
}
Protected Sub Page_Load(ByVal sender As Object, _
        ByVal e As System.EventArgs) Handles Me.Load
    If SampleUserControl <> Nothing Then
       ' Place code manipulating SampleUserControl here.
    End If
End Sub

Caching the Page and User Controls for Different Durations

You can set different output cache duration values for a page and for user controls on the page. If the page output cache duration is longer than the user control output cache duration, the page output cache duration takes precedence. For example, if page output caching is set to 100 seconds and the user control output caching is set to 50 seconds, the entire page, including the user control, is stored in the output cache for 100 seconds, regardless of the shorter setting for the user control.

The following code example shows the effect of a longer cache duration in the page than in a user control. The page is configured to be cached for 100 seconds.

<%@ Page language="C#" %>
<%@ Register tagprefix="SampleControl" tagname="Time" src="uc01.ascx" %>
<%@ OutputCache duration="100" varybyparam="none" %>

<SampleControl:Time runat="server" /><br /> <br /> <br />

This page was most recently generated at:<p>

<% string t = DateTime.Now.ToString(); 
    Response.Write(t); %>
<%@ Page language="VB" %>
<%@ Register tagprefix="SampleControl" tagname="Time" src="uc01.ascx" %>
<%@ OutputCache duration="100" varybyparam="none" %>

<SampleControl:Time runat="server" /><br /> <br /> <br />

This page was most recently generated at:<p>
<% Dim t As String = DateTime.Now.ToString()
Response.Write(t) %>

The following code example shows the user control included in the page. The cache duration for the control is set to 50 seconds.

<% @Control language="C#" %>
<% @OutputCache duration="50" varybyparam="none" %>

This user control was most recently generated at:<p>
<% string t = DateTime.Now.ToString(); 
    Response.Write(t); %>
<% @Control language="VB" %>
<% @OutputCache duration="50" varybyparam="none" %>

This user control was most recently generated at:<p>
<% Dim t As String = DateTime.Now.ToString()
Response.Write(t) %>

If the page output cache duration is less than that of a user control, the user control will be cached until its duration has expired, even after the remainder of the page is regenerated for a request. For example, if page output caching is set to 50 seconds and the user control's output caching is set to 100 seconds, the user control expires once for every two times the rest of the page expires.

The following code shows the markup for a page that contains the user control with a longer cache duration than that of the page. The page is configured to be cached for 50 seconds.

<%@ Page language="C#" %>
<%@ Register tagprefix="SampleControl" tagname="Time" src="uc2.ascx" %>
<%@ OutputCache duration="50" varybyparam="none" %>

<SampleControl:Time runat="server" /><br /> <br /> <br />

This page was most recently generated at:<p>
 <% string t = DateTime.Now.ToString(); 
    Response.Write(t); %>
<%@ Page language="VB" %>
<%@ Register tagprefix="SampleControl" tagname="Time" src="Uc2.ascx" %>
<%@ OutputCache duration="50" varybyparam="none" %>

<SampleControl:Time runat="server" /><br /> <br /> <br />

This page was most recently generated at:<p>
 <% Dim t As String = DateTime.Now.ToString()
Response.Write(t) %>

The following code shows the user control included in the page. The cache duration for the control is set to 100 seconds.

<% @Control language="C#" %>
<% @OutputCache duration="100" varybyparam="none" %>

This user control was most recently generated at:<p>

<% string t = DateTime.Now.ToString(); 
    Response.Write(t); %>
<% @Control language="VB" %>
<% @OutputCache duration="100" varybyparam="none" %>

This user control was most recently generated at:<p>
<% Dim t As String = DateTime.Now.ToString()
Response.Write(t) %>

See Also

Concepts

ASP.NET Caching Overview

Dynamically Updating Portions of a Cached Page

Caching Multiple Versions of a Page

Caching Application Data

Cache Configuration in ASP.NET

Other Resources

What's New in ASP.NET Caching