Home   |   QuickStart Welcome   |   ASP.NET   |   Web Services   |   How Do I...?   
  |   I want my samples in...      

ASP.NET 2.0 Quickstart Tutorials

Page Fragment Caching

In addition to output caching an entire page, ASP.NET provides a simple way for you to output cache regions of page content, which is appropriately named fragment caching. You delineate regions of your page with a user control, and mark them for caching using the @ OutputCache directive introduced in the previous section. This directive specifies the duration (in seconds) that the output content of the user control should be cached on the server, as well as any optional conditions by which it should be varied. For example, the following directive instructs ASP.NET to output cache the user control for 120 seconds, and to vary the caching using the "CategoryID" and "SelectedID" querystring or form post parameters.

<%@ OutputCache Duration="120" VaryByParam="CategoryID;SelectedID"%>

The VaryByParam attribute is extremely powerful and allows user control authors to instruct ASP.NET to cache/store multiple instances of an output cache region on the server. For example, the following URLs to the host page of the previous user control cache separate instances of the user control content.


Logic within a user control can then dynamically generate different content (which is cached separately) depending on the arguments provided.

In addition to supporting the VaryByParam attribute, fragment caching also supports a VaryByControl attribute. Whereas the VaryByParam attribute varies cached results based on name/value pairs sent using POST or GET, the VaryByControl attribute varies the cached fragment by controls within the user control. For example:

<%@ OutputCache Duration="120" VaryByParam="none" VaryByControl="Category" %>

Note that similar to output-cached pages, explict use of VaryByParam is required even if it is not used. If the user control contained a drop-down select box control named Category, the user control's output would vary based on the selected value within that control.

Just as it is possible to nest user controls recursively within a page (that is, a user control declared within another server control), it is also possible to nest output-cached user controls recursively. This provides a powerful composition model that enables cached regions to be composed of further subcached regions. The following sample code demonstrates how to cache two menu sections of a page using a declarative user control.

<%@ Page Language="C#" %>
<%@ Register TagPrefix="Acme" TagName="Menu" Src="Menu.ascx" %>

          <Acme:Menu Category="LeftMenu" runat=server/>
          <h1>Hi, the time is now: <%=DateTime.Now%> </h1>
          <Acme:Menu Category="RightMenu" runat=server/>

The following sample code shows the implementation of the "Acme:Menu" user control with caching support.

<%@ Control Language="C#" ClassName="AcmeMenu" %>
<%@ OutputCache Duration="120" VaryByParam="none" %>

<script runat=server>

    public String Category;

    void Page_Load(Object sender, EventArgs e)  {

        AdoConnection conn = new AdoConnection("MyDSN");

        MyMenu.DataSource = conn.Execute("select * from menu where category=" + Category );


<asp:datagrid id="MyMenu" runat=server/>

Note that this example output caches the response of each user control for a period of 120 seconds. All logic necessary to recreate each menu user control in the event of a cache miss (either because 120 seconds has expired or because memory conditions on the server have become scarce) is encapsulated cleanly within the user control.

The following example shows simple fragment caching. The sample caches the output from a control that retrieves data from an SQL Server database, while keeping the dynamic properties of the parent page. You can see that the page is dynamic because the time is updated with every refresh, while the control is only updated every 60 seconds.

VB Fragment Cache
Run Sample View Source

Note: Attempts to programmatically manipulate an output-cached control from its containing page result in an error. For example, attempts to use a declarative data binding expression on the user control tag generates parser errors, as shown in the following code.

<!-- The following tags generate parser errors. -->
<Acme:Menu Category='<%# Container.DataItem("Category")'  runat="server"/>

The reason for this is simple. In cases when the content of a user control is output cached, an instance of the control is created only on the first request; thus, once cached, the control is no longer available. Instead, you should encapsulate all the logic necessary to create the content of a user control directly within the control itself; this is typically done within the user control's Page_Load event or Page_PreRender event.

You can declare and use other declarative property parameters to customize the control. For example, the previous user control can be customized as follows:

<Acme:Menu Category="LeftMenu" runat=server/>
<Acme:Menu Category="RightMenu" runat=server/>

These declarations cause the appropriate code to be generated and executed by the page compiler in the event that the control is created as a result of a cache miss. User control developers can then access these settings just as they would in a non-cached user control scenario.

Fragment Caching API New in 2.0

In addition to using the @ OutputCache directive, you can now programatically adjust the caching options for user controls using the CacheAPI. In the following example, the control varies the time its cached for based on the state that is selected in the dropdown. You can see the time the control was rendered and the time when the cache entry will be cleared.

VB Fragment Cache API
Run Sample View Source