Lesson 1: Caching Web Forms
Caching an item incurs considerable overhead, so it s important to choose the items to cache wisely. A Web form is a good candidate for caching if it is frequently used and does not contain data that frequently changes. By storing a Web form in memory, you are effectively freezing that form s server-side content so that changes to that content do not appear until the cache is refreshed.
In this lesson, you ll learn how to cache Web forms and how to control how long they are stored in memory. You ll also learn about caching multiple responses from a single Web form.
After this lesson, you will be able to
Cache a Web form response and control how long it is stored in memory
Store multiple responses for a single Web form
Use custom strings to cache multiple responses for a single Web form
Cache a response from within code
Control whether the cached response is stored on the server, on the client, or elsewhere
Estimated lesson time: 20 minutes
Using the OutputCache Directive
Use the @OutputCache page directive to cache a Web form in the server s memory. The @OutputCache directive s Duration attribute controls how long the page is cached. For example, the following Web form is cached for 60 seconds:
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebFormCaching.aspx.vb" Inherits="MCSDWebAppsVB.WebFormCaching"%> <%@ OutputCache Duration="60" VaryByParam="None" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <body> <form method="post" runat="server"> <h2>Caching Web Forms</h2> <hr> <p>Click Refresh to see how server-side information is cached.</p> <p>Time this page was cached (server-side code): <% Response.Write(Now.ToString()) %> </p> <p>Current time (client-side code): <script>document.write(Date());</script> </p> </form> </body> </HTML>
The first time any user requests this Web form, the server loads the response in memory and retains that response for 60 seconds. Any subsequent requests during that time receive the cached response.
After the cache duration has expired, the next request for the Web form generates a new response, which is then cached for another 60 seconds. Thus the server processes the preceding Web form once every 60 seconds at most.
Caching Multiple Responses from a Single Web Form
When used on a Web form, the OutputCache directive has two required attributes: Duration and VaryByParam. The VaryByParam attribute lets you cache multiple responses from a single Web form based on varying HTTP POST or query string parameters. Setting VaryByParam to None caches only one response for the Web form, regardless of the parameters sent.
For example, the following Web form caches a different response for each different selection from the drpTimeZone control:
<%@ OutputCache Duration="60" VaryByParam="drpTimeZone" %> <%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebFormCache2.aspx.vb" Inherits="MCSDWebAppsVB.WebFormCache2"%> <HTML> <body> <form method="post" runat="server"> <h2>Caching Multiple Versions of a Web Form</h2> <hr> <p>Select a time zone and click Submit to see how server-side information is cached.</p> <asp:DropDownList runat="server"> <asp:ListItem Value="1">GMT+1</asp:ListItem> <asp:ListItem Value="2">GMT+2</asp:ListItem> <asp:ListItem Value="0" Selected="True">GMT</asp:ListItem> <asp:ListItem Value="-1">GMT-1</asp:ListItem> <asp:ListItem Value="-2">GMT-2</asp:ListItem> </asp:DropDownList><INPUT type="submit" value="Submit"> <p>Time this page was cached (server-side code): <% Response.Write(DateTime.Now.AddHours(Val(drpTimeZone.SelectedItem.Value))) %> </p> <p>Current time (client-side code): <script>document.write(Date());</script> </p> </form> </body> </HTML>
At run time, up to five different responses will be cached for this Web form one for each possible selection from the drpTimeZone control.
You can also cache multiple responses from a single Web form using the VaryByHeaders or VaryByCustom attribute. For example, the following OutputCache directive caches different responses based on the requested language:
<%@ OutputCache Duration="120" VaryByParam="None" VaryByHeader="Accept-Language" %> <%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebFormCache3.aspx.vb" Inherits="MCSDWebAppsVB.WebFormCache3"%> <HTML> <body> <form method="post" runat="server"> <h2>Caching Multiple Versions of a Web Form by Header</h2> <hr> <p>Change your regional settings in the Windows Control panel then click Submit below to see how different versions of this page are cached.</p> <INPUT type="submit" value="Submit" > <p>Request language: <% Response.Write(Request.Headers.GetValues("Accept-Language")(0)) %> </p> <p>Time this page was cached (server-side code): <% Response.Write(DateTime.Now) %> </p> <p>Current time (client-side code): <script>document.write(Date());</script> </p> </form> </body> </HTML>
This Web form caches a different response for each request that has a different Accept-Language header.
The VaryByCustom attribute lets you cache different responses based on a custom string. To use VaryByCustom, override the GetVaryByCustomString method in the Web application s Global.asax file. For example, the following code creates a custom string (appName) that allows different responses to be cached for different client browsers:
Visual Basic .NET
' From Global.asax Public Overrides Function GetVaryByCustomString(ByVal context As HttpContext, _ ByVal arg As String) As String If (arg = "appName") Then Return "appName=" & context.Request.Browser.Browser End If End Function
Visual C#
// From Global.asax public override string GetVaryByCustomString(HttpContext context, string arg ) { if (arg == "appName") return "appName=" + context.Request.Browser.Browser; else return ""; }
The following Web form caches different responses based on the client s browser using the appName custom string created in the preceding code:
<%@ OutputCache Duration="120" VaryByParam="None" VaryByCustom="appName" %> <%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebFormCache4.aspx.vb" Inherits="MCSDWebAppsVB.WebFormCache4"%> <body> <form method="post" runat="server"> <h2>Caching Multiple Versions of a Web Form by Custom String</h2> <hr> <p>View this page from different browsers and click Submit below to see how different versions of this page are cached.</p> <INPUT type="submit" value="Submit" lang="en-uk"> <p>Client browser: <script>document.write(navigator.appName)</script> </p> <p>Time this page was cached (server-side code): <% Response.Write(DateTime.Now) %> </p> <p>Current time (client-side code): <script>document.write(Date());</script> </p> </form> </body> </html>
Controlling Caching in Code
The preceding sections show how to control caching within a Web form s HTML using the OutputCache directive. You can also control Web form caching within code using the Response object s Cache property, which returns an HttpCachePolicy object for the response. The HttpCachePolicy object provides members that are similar to the OutputCache directive s attributes. Table 12-1 compares the key HttpCachePolicy members and the OutputCache attributes.
HttpCachePolicy member | OutputCache attribute | Use to |
VaryByParams | VaryByParam | Cache multiple responses for a single Web form based on an HTTP POST parameter or query string. |
VaryByHeaders | VaryByHeader | Cache multiple responses for a single Web form based on the HTTP request header sent from the client. |
SetVaryByCustom | VaryByCustom | Cache multiple responses for a single Web form based on a custom string. |
SetExpires | Duration | Set the amount of time a response is cached. |
SetSlidingExpiration | N/A | Change between an absolute expiration and sliding expiration. |
SetCacheability | Location | Specify where the response is cached. |
SetAllowResponseInBrowserHistory | N/A | Cache the response in the client browser s history regardless of the SetCacheability setting. |
AddValidationCallback | N/A | Register a callback function to validate the cached response before returning the response to the client. |
SetRevalidation | N/A | Set a flag to revalidate the cached response stored on the proxy server, host server, or at all locations. |
SetValidUntilExpires | N/A (True by default) | Cause ASP.NET to ignore cache invalidation headers sent by some client browsers when the user clicks Refresh. |
For example, the following code caches the Web form s response for 5 seconds:
Visual Basic .NET
Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' Display time page was cached. lblTime.Text = Now ' Set OutputCache Duration. Response.Cache.SetExpires(Now.AddSeconds(5)) ' Set OutputCache VaryByParams. Response.Cache.VaryByParams("None") = True ' Set OutputCache Location. Response.Cache.SetCacheability(HttpCacheability.Public) End Sub
Visual C#
private void Page_Load(object sender, System.EventArgs e) { // Display time page was cached. lblTime.Text = System.DateTime.Now.ToString(); // Set OutputCache Duration. Response.Cache.SetExpires(System.DateTime.Now.AddSeconds(5)); // Set OutputCache VaryByParams. Response.Cache.VaryByParams["None"] = true; // Set OutputCache Location. Response.Cache.SetCacheability(HttpCacheability.Public); }
The preceding code is equivalent to the following OutputCache directive:
<%@ OutputCache Duration="5" VaryByParam="None" Location="Any" %>
Controlling Where Items Are Cached
The OutputCache directive s Location attribute and the HttpCachePolicy object s SetCacheability property determine where Microsoft ASP.NET stores cached responses. By default, ASP.NET caches responses at any available location that accepts cache items the client, proxy servers, or the host server. In practice, those locations might or might not allow caching, so you can think of the Location/SetCacheability setting as more of a request than a command. Table 12-2 describes the Location/SetCacheability settings.
Location setting | SetCacheability setting | Caches response at |
Any | HttpCacheability.Server | Any available location: client, proxy server, or host server. |
Client | HttpCacheability.Private | Client on which the request originated. |
Downstream | HttpCacheability.Public | Client or proxy server. |
None | HttpCacheability.NoCache | No location. This setting disables caching. |
Server | HttpCacheability.ServerAndNoCache | Host server on which request is processed. |
ServerAndClient | HttpCacheability.ServerAndPrivate | Host server on which request is processed and client on which request originated. |
In Microsoft .NET Framework version 1.1 and later, you can override the cache location settings using the HttpCachePolicy object s SetAllowResponseInBrowserHistory method. Setting that method to True allows the response to be stored in the client s history folder even if the location setting is None or Server.