Using Page Fragment Caching


In several situations, caching part of a page makes more sense than caching the whole page. For example, if you were randomly displaying banner advertisements on a Web page, you would not want to cache the part that contains the banner advertisements because caching the page would result in the same banner advertisement being displayed each time the page is requested .

Page fragment caching is implemented with user controls. You define different areas of a page by creating separate user controls for each area of the page. Within each user control, you can use the OutputCache directive to indicate how the output of the control is cached.

NOTE

To learn more details about user controls, see Chapter 5, "Creating Custom Controls with User Controls."


Imagine that the home page for your Web site contains randomly selected banner advertisements that are displayed at the top and bottom of the page. Furthermore, imagine that the body of the page displays a list of products from the Products database table. In that case, you would want to cache the area of the page that displays the list of products, but not the areas of the page that display the banner advertisements.

The page in Listing 17.10 illustrates how you can cache the body of the page, but not the banner advertisements displayed at the top and bottom (see Figure 17.3).

Listing 17.10 Home.aspx
 <%@ Register TagPrefix="myControls" TagName="PageContents" SRC="PageContents.ascx" %> <html> <head><title>Home.aspx</title></head> <body bgcolor="#eeeeee"> <asp:AdRotator   ID="myTopAd"   KeywordFilter="Top"   AdvertisementFile="AdFile.xml"   Runat="Server" /> <myControls:PageContents   CategoryID="2"   Runat="Server"/> <asp:AdRotator   ID="myBottomAd"   Align="Center"   KeywordFilter="Bottom"   AdvertisementFile="AdFile.xml"   Runat="Server" /> <hr> ( page generated: <%=Now()%> ) </body> </html> 

The C# version of this code can be found on the CD-ROM.

Figure 17.3. Partial page caching.

graphics/17fig03.jpg

The body of the page in Listing 17.10 contains a user control named PageContents . This user control, contained in Listing 17.11, displays a list of products for a particular category.

Listing 17.11 PageContents.ascx
 <%@ OutputCache Duration="60" VaryByParam="*" %> <%@ Import Namespace="System.Data.SqlClient" %> <Script Runat="Server"> Public CategoryID As Integer Sub Page_Load   Dim conNorthwind As SqlConnection   Dim strSelect As String   Dim cmdSelect As SqlCommand   conNorthwind = New SqlConnection( "Server=Localhost;UID=sa;PWD=secret;Database=Northwind" )   strSelect = "Select * From Products Where CategoryID=@CategoryID"   cmdSelect = New SqlCommand( strSelect, conNorthwind )   cmdSelect.Parameters.Add( "@CategoryID", CategoryID )   conNorthwind.Open()     dgrdProducts.DataSource = cmdSelect.ExecuteReader()     dgrdProducts.DataBind()   conNorthwind.Close() End Sub </Script> <p> <h1>Welcome to Our Web Site!</h1> Here is a list of our current products: <p> <asp:DataGrid   ID="dgrdProducts"   Runat="Server" /> ( Control generated: <%=Now%> ) <p> 

The C# version of this code can be found on the CD-ROM.

The user control in Listing 17.11 displays the text Welcome to Our Web Site! and a DataGrid that contains a list of products.

The PageContents user control includes an OutputCache directive, which causes the output of the user control to be cached for 60 seconds.

The page that contains the user control, Home.aspx , is not cached. However, it contains a cached user control. The end result is that the banner advertisements in Home.aspx are not cached, but the database data displayed by the PageContents user control is cached.

NOTE

What happens if you use the same cached user control in multiple pages? By default, the output of each user control is cached separately, If you want to share the same cached output across multiple user controls in order to preserve memory, then you can use the Shared attribute with the OutputCache directive like this:

 
 <%@ OutputCache Duration="60" VaryByParam="*" Shared="true" %> 

Varying Page Fragment Caching by Parameter

You can use the VaryByParam attribute with the OutputCache directive in a user control. This means that you can cache different versions of the output of a user control depending on the query string passed to the control.

Imagine, for example, that you want to create a user control that displays a menu of options. When a user clicks an option, you want the currently selected option to be highlighted. The user control in Listing 17.12 illustrates how to do so (see Figure 17.4).

Listing 17.12 Menu.ascx
 <%@ OutputCache Duration="300" VaryByParam="menuID" %> <Script Runat="Server"> Dim strMenuID As String Sub Page_Load   strMenuID = Request.Params( "menuID" )   If strMenuID = Nothing Then     strMenuID = "0"   End If End Sub </Script> <table border="2" bordercolor="black"   cellpadding="5" cellspacing="0"   bgcolor="#eeeeee"> <tr>   <td>   <% If strMenuID = "0" Then %>   <b>Our Company</b>   <% Else %>   <a href="ourcompany.aspx?menuID=0">Our Company</a>   <% End If %>   </td>   <td>   <% If strMenuID = "1" Then %>   <b>Our Services</b>   <% Else %>   <a href="ourservices.aspx?menuID=1">Our Services</a>   <% End If %>   </td>   <td>   <% If strMenuID = "2" Then %>   <b>Our Products</b>   <% Else %>   <a href="ourproducts.aspx?menuID=2">Our Products</a>   <% End If %>   </td> </tr> </table> (menu generated: <%=Now() %> ) 

The C# version of this code can be found on the CD-ROM.

Figure 17.4. Using VaryByParam with partial page caching.

graphics/17fig04.jpg

The user control in Listing 17.12 contains an OutputCache directive, which causes the output of the control to be cached for 300 seconds (5 minutes). The VaryByParam attribute indicates that different versions of the output of the control should be cached depending on the value of the menuID parameter.

In the Page_Load subroutine, the value of the menuID parameter is retrieved from the query string passed to the page. The menuID highlights the currently selected menu option.

The page in Listing 17.13 illustrates how you can use the Menu control in an ASP.NET page.

Listing 17.13 OurCompany.aspx
 <%@ Register TagPrefix="myControls" TagName="Menu" SRC="menu.ascx" %> <html> <head><title>OurCompany.aspx</title></head> <body bgcolor="lightblue"> <myControls:Menu   Runat="Server" /> <h1>Our Company</h1> <asp:Panel   width="400"   style="padding: 10px"   BorderStyle="solid"   BackColor="White"   Runat="Server"> Our company specializes in creating large scale Web sites for commercial clients. Visit the different areas of our Web site to learn more! </asp:Panel> <hr> ( page generated: <%=now() %> ) </body> </html> 

The C# version of this code can be found on the CD-ROM.

The page in Listing 17.13 registers the user control by using the Register page directive. The control is declared in the body of the page.

Examining the Limitations of Page Fragment Caching

You should be aware that you are significantly limited on how you can use a user control that contains an OutputCache directive. If you enable caching for a user control, you can no longer programmatically access the control in its containing page.

For example, suppose you declare a cached user control like this:

 
 <myControls:PageContents   ID="ctlContents"   Runat="Server"/> 

Since the control is cached, you cannot programmatically set a property of the user control in a page like this:

 
 ctlContents.Message = "Hello!" 

You also should not attempt to use data-binding syntax with a cached user control. For example, never attempt to declare a cached user control like this:

 
 <myControls:PageContents   CategoryID='<%# CategoryID %>'   Runat="Server"/> 

This declaration of the cached user control generates an error message.

Nothing is wrong, however, with declaratively setting a property of a cached user control like this:

 
 <myControls:PageContents   CategoryID="2"   Runat="Server"/> 

In this case, the value of the CategoryID property is set declaratively.



ASP.NET Unleashed
ASP.NET 4 Unleashed
ISBN: 0672331128
EAN: 2147483647
Year: 2003
Pages: 263

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net