JavaScript EditorJavascript debugger     Javascript examples


Team LiB
Previous Section Next Section

Using Output Caching

Output caching allows you to cache the rendered output of any ASP.NET Web Forms page or user control, and to serve subsequent requests from the cache. This can substantially reduce the processor load on the Web server because the processor isn’t busy rendering pages whose content hasn’t changed. The two basic techniques for enabling output caching are declarative and programmatic. The declarative technique uses the @ OutputCache directive and its associated attributes to enable output caching; the programmatic technique uses the Response.Cache property to programmatically set caching parameters.

Using the @ OutputCache Directive

The simplest method to quickly set up output caching for a given page or user control is to add the @ OutputCache directive. This directive and its attributes allow you to set the length of time the content should be cached, the location where it should be cached, and any parameters to be used to cache multiple versions of a page. Table 12-1 describes the available attributes for the @ OutputCache directive.

Table 12-1: @ OutputCache Attributes

Attribute

Description

Duration

Sets the number of seconds to cache the content. This attribute is required.

Location

Sets the location to be used to cache content. This can be one of the following values:

Any Content can be cached by any cache-aware application (such as a proxy server) in the request stream, by the Web server, or by the client browser. This is the default value.

Client Content is cached by the requesting client’s browser.

Downstream Content can be cached by any cache-aware application downstream of the Web server fulfilling the request.

Server Content is cached on the Web server.

None No caching.

You can use the Location attribute with Web Forms pages only.

Shared

New in ASP.NET 1.1, this attribute specifies whether or not a cached user control can be shared across multiple pages. If set to true, a single cached copy of the user control is shared among multiple pages within the application. If set to false, a separate copy of the user control will be cached for each page that uses the control. The default is false.

This attribute is valid for user controls only.

VaryByControl

Sets the names of properties of a user control by which to vary the caching of the user control output. Multiple properties are separated by semicolons. You can use this attribute with user controls only.

VaryByCustom

Allows varying of cached content by browser user agent, browser capabilities, or custom logic. When set to any value other than browser, this attribute requires that the HttpApplication.GetVaryByCustomString be overridden in Global.asax to implement the custom logic.

VaryByHeader

Allows varying of cached content based on the value of one or more HTTP request headers. Multiple properties are separated by semicolons.

You can use this attribute with Web Forms pages only.

VaryByParam

Allows varying of cached content based on the value of one or more querystring values sent with a GET request, or form fields sent with a POST request. Multiple key or field names are separated by semicolons. You can also set the value of this attribute to * to vary by all parameters, or to None to use the same cached page regardless of GET/POST parameters.

This attribute is required.

The VaryByX attributes are among the most important features of the @ OutputCache directive. These attributes make it possible to cache pages and user controls even when those pages are dynamically generated based on querystring values, form field values, HTTP header values, or even browser capabilities.

The Duration attribute lets you limit the length of time that output is cached. For pages that are updated periodically, but not as frequently as every request, the Duration attribute allows you to fine-tune the output caching so that you can maximize the benefit gained by caching while being reasonably sure that users will not get stale content. For example, if you had a page that, on average, was updated every two hours, you could set the Duration attribute of the @ OutputCache directive to 900. This would cache the output of the page for 900 seconds (15 minutes) from the last time the page was requested (subject to the VaryBy attributes). This would ensure that the page would need to be rendered only once every 15 minutes, regardless of how many requests were received for the page, and that there would be only a 15-minute window in which users could get a cached page rather than updated data.

The Shared attribute allows you to conserve memory by making a single cached copy of a user control available to multiple pages within your application. Without setting this attribute to true, a separate copy of the user control is cached for each page that uses the user control.

Finally, the Location attribute determines where the output cache is located. Setting certain values for the Location attribute causes ASP.NET to set the If Modified-Since HTTP header to allow caching of page or control output.

Cache Web Forms output

  1. Open Visual Studio .NET and create a new Web Application project called Chapter_12.

  2. Rename the initial default page WebForm1.aspx to OutputCache.aspx by selecting it in the Solution Explorer window, then selecting File, and then selecting Save WebForm1.aspx As. In the resulting dialog box, type OutputCache.aspx as the new filename.

  3. Add two labels to the form. Using the Properties window, change the ID property of the first label from Label1 to Message. Change the Text property of the second label to The text above was rendered with an ASP.NET Label Server Control, then the output was cached for 10 seconds. The resulting screen should look like the following illustration:

    Click To expand
  4. Select View, and then select Code, or press F7 to move to the code window.

  5. Scroll down to the Page_Load event handler and add the following code:

    Message.Text = DateTime.Now.ToString();
  6. Save the open files and project, and then build the project.

  7. Browse the page, and then press F5 to refresh the page in the browser. Each time you refresh the browser (as long as your refresh requests are at least one second apart), the time displayed by the first label will change.

  8. Go back to OutputCache.aspx and switch to HTML view. Add an @ OutputCache directive at the top of the page, with the Duration attribute set to 10 and the VaryByParam attribute set to None. This directive should appear on the line directly below the @ Page directive. The complete directive should look like this:

    <%@ OutputCache Duration="10" VaryByParam="None" %>
  9. Save OutputCache.aspx. Because you’ve changed only the .aspx file, you don’t need to build the project—the changed page will be dynamically compiled the next time it’s requested.

  10. Browse the page using Microsoft Internet Explorer, and again refresh the browser. The time displayed should change only about once every 10 seconds. The screen should look similar to the following illustration:

    Click To expand
    Note 

    When you look at the preceding illustration, you’ll notice that even though we renamed the form from WebForm1.aspx to OutputCache.aspx, the title (shown in the title bar) remains WebForm1. Microsoft Visual Studio .NET gives the filename as the default title when the form is created, but does not update that when the file is renamed. You can update the title yourself in the properties of the DOCUMENT object for the page, or you can edit the HTML <title> tag directly.

Caching User Controls

Caching the output of Web Forms pages can be very useful, but sometimes you might not be able to cache an entire page because its content is updated too frequently. Don’t fret—you can still take advantage of output caching by moving less frequently updated portions of a page into one or more ASP.NET user controls, and then caching the output of the user controls.

Caching the output of user controls is nearly identical to caching page output. For user controls, you add the @ OutputCache directive to the user controls themselves instead of adding the directive to the page containing the user controls. As noted in the table on page 443, certain @ OutputCache attributes, such as Location and VaryByHeader, can be used only with Web Forms pages; they will cause an error if included in a user control.

Note 

In addition to the technique demonstrated in the following step-by-step procedure, you can also develop user controls programmatically, using the code-behind file exclusively (while the .ascx file merely has an @Control directive pointing to the code-behind file). With this technique, you can still cache the output of the user control by adding the PartialCaching attribute (new in ASP.NET 1.1) to the class definition for the control, as shown in the following code example:

[PartialCaching(30)] _
public class FragmentCache : System.Web.UI.UserControl
{
   protected void Page_Load(object sender, EventArgs e)
   {
      Message.Text = DateTime.Now.ToString();
   }
}

Cache user control output

  1. In the same project as the previous exercise, add another item: Right-click on the root of the project in the Solution Explorer. From the context menu, select Add, then select Add Web User Control. Type the name of the user control as FragmentCache.ascx.

  2. The default layout in User Controls in Visual Studio .NET is Flow Layout rather than Grid Layout. Add two labels (as we did in the last example, Outputcache.aspx) by dragging one label from the toolbox to the form, clicking just after the label and pressing Enter. Then add the second label. In the Properties window, change the ID property of the first label from Label1 to Message. In the properties window, change the Text property of the second label to The text above was rendered from the User Control.

  3. Switch to HTML mode and add the following @ OutputCache directive to the top of the HTML, just below the @ Control directive:

    <%@ OutputCache Duration="10" VaryByParam="None" %>
  4. Select View, and then select Code, or press F7 to move into the code window.

  5. Scroll down to the Page_Load event handler and add the following code:

    Message.Text = DateTime.Now.ToString();
  6. Save FragmentCache.ascx and its code-behind file.

  7. In the same project, add a Web Form and type its name as FragmentCache.aspx.

  8. Add two labels to the form about midway down the page, leaving an equal amount of space at the top of the page as that taken up by the two labels. Using the property window, change the name of the first label from Label1 to Message. Change the text in the second label to The text above was rendered from the Web Forms page.

  9. Select View, and then select Code, or press F7 to move to the code window. Scroll down to the Page_Load event handler and add the following code:

    Message.Text = DateTime.Now.ToString();
  10. Switch back to FragmentCache.aspx by clicking its tab at the top of the editor window. You should be in Design mode. If not, switch to Design mode.

  11. Find FragmentCache.ascx in the Solution Explorer. Drag it onto the form. No matter where you place it, it will end up in the upper left hand corner of the design window.

  12. Save FragmentCache.aspx (and any other unsaved files), and build the project.

  13. Browse the page using Internet Explorer, and refresh the browser. The screen will look similar to the illustration on the next page.

    Click To expand

When you first browse the page, both timestamps will be the same. If you click the browser’s Refresh button several times, you’ll notice that the time displayed by the page is updated with each page request, while the time displayed by the user control is updated only once every 10 seconds.

Tip 

As mentioned earlier in this chapter, if you’re using a user control from numerous pages within your application and want to conserve memory, you can add the Shared attribute to the @OutputCache directive, which will allow a single cached version of the control to be shared across all of the pages within your application that use the control:

<%@ OutputCache Duration="10" VaryByParam="None" Shared="true" %>

Of course, if the user control relies on input from each individual page, using the Shared attribute might not be appropriate. But in cases in which the output of the control will be the same for all pages, it’s a handy way to avoid eating up memory unnecessarily.

Caching Multiple Versions of Output

If your page uses either querystring values (GET requests) or form fields (POST requests) to dynamically generate content, you can still use output caching by adding the VaryByParam attribute to the @ OutputCache directive with the values set to the names of the parameters by which to vary the cache. ASP.NET will cache a copy of the output from the page for each unique combination of parameters, so any user who requests the page within the period specified by the Duration attribute with the same set of parameters as a previous request will have that request fulfilled from the cache.

Important 

Because ASP.NET will cache a copy of the output for each unique combination of parameters, you should avoid using an excessive number of parameters to vary the cache. This can result in a significant amount of memory use. This caution applies to the VaryByHeader and VaryByControl attributes as well.

Use VaryByParam to cache multiple versions of a Web Form

  1. In the same project as the last exercise, add another Web Form named VaryByParam.aspx.

  2. Add two labels to the form, one above the other. Add a text box on the right of the top label. Using the property window, change the Text property of the first label to Enter Your Name:. Change the ID property of the textbox to Name. Set the Text property of the second label to The text above was rendered with an ASP.NET Label Server Control, then the output was cached for 30 seconds. Set the Visible property of this second label to False. The result should look like the following illustration.

    Click To expand
  3. Switch to HTML view and add an @ OutputCache directive to the page, specifying the duration as 30 seconds and the parameter to vary by the name of the TextBox control:

    <%@ OutputCache Duration="30" VaryByParam="Name" %>
  4. Select View, and then select Code, or press F7 to move to the code window.

  5. Scroll down to the Page_Load event handler and add the following code:

    if (IsPostBack  Name.Visible = false Label2.Visible = true Label1.Text = "Hello " + Name.Text Label1.Text += ". The current date and time is " Label1.Text += DateTime.Now.ToString() }
  6. Save VaryByParam.aspx and its code-behind file, and then build the project.

  7. Browse VaryByParam.aspx using Internet Explorer. The initial output will look similar to the following illustration.

    Click To expand
  8. Enter your name and press Enter. The output will look similar to the illustration on the next page.

    Click To expand

If you click the browser’s Refresh button (and click Retry or OK to repost the form), the page will refresh from the cache. If you click Back and enter a different name, you will get a fresh version of the page. Try entering different names, refreshing, and then going back and entering the same names as earlier requests. You should see that all requests with the same name are cached for 30 seconds.

Using Response.Cache

In addition to using the @ OutputCache directive, you can also enable output caching for a page by using the methods of the HttpCachePolicy class, which is exposed by the Response.Cache property.

The code required to perform the same output caching as shown in the OutputCache.aspx example is shown here. Place this code in the Page_Load event handler:

Message.Text = DateTime.Now.ToString() Response.Cache.SetExpires(DateTime.Now.AddSeconds(10)) Response.Cache.SetCacheability(HttpCacheability.Public);

This code is equivalent to an @ OutputCache directive with a duration of 10 and a location of Any (or no location attribute). To set the cache location to client, you would use the HttpCacheability.Private enumeration member instead of HttpCacheability.Public. To turn off caching entirely, you would use HttpCacheability.NoCache.

In addition to the SetExpires and SetCacheability methods shown in the preceding code, you can also use the SetNoServerCaching method in combination with the code from ResponseCache.aspx to provide the equivalent of an @ OutputCache directive with a duration of 10 and a location of Downstream.


Team LiB
Previous Section Next Section


JavaScript EditorJavascript debugger     Javascript examples