-
You can use the Substitution control to create areas on a web page that can be dynamically updated and subsequently integrated into cached pages.
1. Plan
Use the Substitution control to specify the portions of the web page where you want to cache the output of dynamic content. For pages where most of the content is cached, the Substitution control provides a simplified solution for partial page caching. You can cache the output of an entire page and then use the Substitution control to specify the portions of the page that are not cached. The cache area is executed only once and will be read from the cache until the cache entry expires or is cleared. Dynamic regions are executed every time the page is requested. This caching model simplifies coding for web pages whose content is mostly static because you don't have to encapsulate this static content in a Web user control to put it in the cache. For example, this caching model is useful for web pages that contain static content (such as news stories) and an AdRotator control that displays advertisements. News stories don't change often, which means they can be cached. You may want to display a new ad each time a user requests the page. The AdRotator control directly supports post-cache replacement, which renders a new ad on each postback of the webpage regardless of whether the webpage is cached.
2. Background
When you cache an ASP.NET web page, by default, all output from the page is cached. On the first request, the page will run and its output will be cached. For subsequent requests, this will be done through caching and the code on that page will not run.
In some cases, you may want to not only cache an ASP.NET web page, but also update selected portions of the page each time the page is requested. For example, you might want to cache a large portion of a page, but need to dynamically update highly time-sensitive information on the page.
You can use the Substitution control to insert dynamic content into cached pages. The Substitution control does not render any markup. Therefore, you need to bind the control to a method in the web page or parent user control. You need to create static methods that return information to be inserted into the web page. Methods called by Substitution controls must meet the following criteria:
·Must be a static method (shared in Visual Basic).
·Must accept parameters of type HttpContext.
·Must return a value of type String.
The Substitution control has no access to other controls on the web page, which means that you cannot inspect or change the values of other controls. However, the code can access the context of the current page using the parameters passed to it.
When the page runs, the Substitution control calls this method and then replaces the Substitution controls on the page with the return value from the method.
code example
The following example demonstrates how to use the Substitution control to create dynamically updateable content on a cached page. The code in the page's Load event updates the Label control with the current time. Because the page's cache duration has been set to 60 seconds, the Label control's text does not change, even if the page is requested multiple times within a 60-second period. The Substitution control on the page calls the static method GetTime, which returns the current time as a string. Each time the web page is refreshed, the value represented by the Substitution control is updated.
<%@ Page Language="C#" %>
<%@ OutputCache Duration=60 VaryByParam="None" %>
<script runat="server">
void Page_Load()
{
Label1.Text = DateTime.Now.ToString();
}
public static String GetTime(HttpContext context)
{
return DateTime.Now.ToString();
}
</script>
<html>
<head runat="server"></head>
<body>
<form id="form1" runat="server">
<div>
<p>
<asp:Label runat="server" ID="Label1" />
</p>
<p>
<asp:Substitution runat="server"
ID="Substitution1"
MethodName="GetTime" />
</p>
<p>
<asp:Button runat="server" ID="Button1" Text="Submit"/>
</p>
</div>
</form>
</body>
</html>
3. Substitution class
Use the Substitution control to specify the portion of the output cached web page that you want to replace the control with dynamic content. The Substitution control provides a simplified solution for caching partial pages for pages where most of the content is to be cached. You can output cache the entire page and then use the Substitution control to specify the portions of the page that are exempt from caching. Areas that need to be cached are executed only once and then read from the cache until the cache item expires or is cleared. Dynamic regions are executed every time the page is requested. This caching model simplifies the code for pages with primarily static content because these portions do not have to be encapsulated for caching in Web user controls. For example, this caching model is useful if the page contains static content (such as a news article) and an AdRotator control that displays ads. News articles don't change, which means they can be cached. However, you want to display a new ad every time a user requests the page. The AdRotator control directly supports post-cache replacement, which renders a new ad when the page is posted back, regardless of whether the page is cached.
Note: The Substitution control can be placed in the user control contained in the cache page. However, you cannot place a Substitution control within an output cache user control.
When the Substitution control is executed, a method that returns a string is called. The string returned by this method is the content to be displayed at the location of the Substitution control on the page. Use the MethodName property to specify the name of the callback method to be called when the Substitution control executes. The specified callback method must be a static method of the page or user control that contains the Substitution control. The signature of the callback method must match the signature of the HttpResponseSubstitutionCallback delegate that accepts an HttpContext parameter and returns a string.
To operate the page's output cache, you can use the @OutputCache directive, the HttpCachePolicy class, or the Cache property.
Another way to use the Substitution control is to use the HttpResponseSubstitutionCallback delegate to implement cache replacement behavior. Additionally, cache replacement behavior can be implemented on controls that directly support cache replacement functionality, such as the AdRotator control.
Example
The following code example demonstrates how to declaratively add a Substitution control to an output cache web page. When the page loads, the user is shown the current date and time in a tab. This area of the page is cached and updated every 60 seconds. When the Substitution control executes, the GetCurrentDateTime method is called. The string returned by GetCurrentDateTime will be displayed to the user. This part of the page is not cached and updated every time the page is refreshed.
<%@ outputcache duration="60" varybyparam="none" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
" http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
<script runat="server" language="C#">
void Page_Load(object sender, System.EventArgs e)
{
// Display the current date and time in the label.
// Output caching applies to this section of the page.
CachedDateLabel.Text = DateTime.Now.ToString();
}
// The Substitution control calls this method to retrieve
// the current date and time. This section of the page
// is exempt from output caching.
public static string GetCurrentDateTime (HttpContext context)
{
return DateTime.Now.ToString ();
}
</script>
<html>
<head runat="server">
<title>Substitution Class Example</title>
</head>
<body>
<form id="form1" runat="server">
<h3>Substitution Class Example</h3>
<p>This section of the page is not cached:</p>
<asp:substitution id="Substitution1"
methodname="GetCurrentDateTime"
runat="Server">
</asp:substitution>
<br />
<p>This section of the page is cached:</p>
<asp:label id="CachedDateLabel"
runat="Server">
</asp:label>
<br /><br />
<asp:button id="RefreshButton"
text="Refresh Page"
runat="Server">
</asp:button>
</form>
</body>