12.3 页面部分缓存
页面部分缓存是指输出缓存页面的某些部分,而不是缓存整个页面内容。实现页面部分缓存有两种机制:一种是将页面中需要缓存的部分置于用户控件(
.ascx
文件)中,并且为用户控件设置缓存功能(包含用户控件的
ASP.NET
页面可设置也可不设置缓存)。这就是通常所说的
“
控件缓存
”
。设置控件缓存的实质是对用户控件进行缓存配置。主要包括以下
3
种方法:一是使用
@ OutputCache
指令以声明方式为用户控件设置缓存功能,二是在代码隐藏文件中使用
PartialCachingAttribute
类设置用户控件缓存;三是使用
ControlCachePolicy
类以编程方式指定用户控件缓存设置。另外,还有一种称为
“
缓存后替换
”
的方法。该方法与控件缓存正好相反,将页面中的某一部分设置为不缓存,因此,尽管缓存了整个页面,但是当再次请求该页时,将重新处理那些没有设置为缓存的内容。
12.3.1 使用@ OutputCache指令
控件缓存与页面输出缓存的
@ OutputCache
指令既有相似之处,又有不同的方面。二者的共同点在于它们的设置方法基本相同,都是文件顶部设置包含属性的
@ OutputCache
指令字符串。不同点包括以下两个方面:一是控件缓存的
@ OutputCache
指令设置在用户控件文件中,而页面输出缓存的
@ OutputCache
设置在普通
ASP.NET
文件中。二是控件缓存的
@ OutputCache
指令只能设置
6
个属性,
Duration
、
Shared
、
SqlDependency
、
VaryByControl
、
VaryByCustom
和
VaryByParam
。而在页面输出缓存的
@ OutputCache
指令字符串中设置的属性多达
10
个。以上是设置控件缓存时需要注意的问题。下面列举了一些利用
@ OutputCache
指令设置控件缓存的示例,其中重点说明了
VaryByParam
和
VaryByControl
等属性应用。
用户控件中的@ OutputCache指令设置源代码
|
<%@ OutputCache Duration="120" VaryByParam="CategoryID;SelectedID"%>
|
以上代码设置用户控件缓存有效期时间是
120
秒,并且允许使用
CategoryID
和
SelectedID
参数来改变缓存。通过
VaryByParam
属性设置,在服务器缓存中可能存储多个用户控件的实例。例如,对于一个包含用户控件的页面,可能存在如下的
URL
链接。
包含用户控件的页面的URL链接
|
http://localhost/mypage.aspx?categoryid=foo&selectedid=0
http://localhost/mypage.aspx?categoryid=foo&selectedid=1
|
当请求如上
URL
地址的页面时,由于控件中
@ OutputCache
指令的设置,尤其是属性
VaryByParam
的设置,那么在服务器缓存中就会存储两个版本的用户控件缓存实例。
控件缓存设置除了支持以上所述
VaryByParam
属性外,还支持
VaryByControl
属性。
VaryByParam
属性基于使用
POST
或者
GET
方式发送的名称
/
值对来改变缓存,而
VaryByControl
属性通过用户控件文件中包含的服务器控件来改变缓存。下面是
VaryByControl
属性的应用示例代码。
用户控件中的@ OutputCache指令设置源代码
|
<%@ OutputCache Duration="120" VaryByParam="none" VaryByControl="Category" %>
|
以上代码设置缓存有效期是
120
秒,并且页面不随任何
GET
或
POST
参数改变(即使不使用
VaryByParam
属性,但是仍然需要在
@ OutputControl
指令中显式声明该属性)。如果用户控件中包含
ID
属性为
“Category”
的服务器控件(例如下拉框控件),那么缓存将根据该控件的变化来存储用户控件数据。
如果读者已经掌握了页面输出缓存的
@ OutputCache
指令设置方法,那么控件缓存的
@ OutputCache
指令也会迎刃而解,无非仅使用其中的
6
个属性而已。然而,可能会产生疑问:如果
ASP.NET
页面和其中包含的用户控件都通过
@ OutputCache
指令设置了缓存,那么缓存该如何运行呢?
遇到这个问题时,应掌握以下
3
个基本原则:一是
ASP.NET
允许在页面和页面的用户控件中同时使用
@ OutputCache
指令设置缓存,并且允许设置不同的缓存过期时间值。二是如果页面输出缓存过期时间长于用户控件输出缓存过期时间,则页面的输出缓存持续时间优先。例如,如果页面输出缓存设置为
100
秒,而用户控件的输出缓存设置为
50
秒,则包括用户控件在内的整个页将在输出缓存中存储
100
秒,而与用户控件较短的时间设置无关。三是如果页面输出缓存过期时间比用户控件的输出缓存过期时间短,则即使已为某个请求重新生成该页面的其余部分,也将一直缓存用户控件直到其过期时间到期为止。例如,如果页面输出缓存设置为
50
秒,而用户控件输出缓存设置为
100
秒,则页面其余部分每到期两次,用户控件才到期一次。
12.3.2 使用PartialCachingAttribute类
使用
PartialCachingAttribute
类可在用户控件的代码隐藏文件中设置有关控件缓存的配置内容。此处应重点了解
PartialCachingAttribute
类的
6
个常用属性和
4
种类构造函数。
6
个常用属性是
Duration
、
Shared
、
SqlDependency
、
VaryByControl
、
VaryByCustom
和
VaryByParam
。这与上文所示的控件缓存
@ OutputCache
指令设置的
6
个属性完全相同,只是所使用的方式不同。在此不对这
6
个属性重复介绍。下面重点说明
PartialCachingAttribute
类的
4
种构造函数,这对于使用该类有着重要意义。
[PartialCaching(int duration)]
这是最为常用的一种格式。其参数
duration
为整数类型,用于设置用户控件缓存有效期时间值。该参数与
@ OutputCache
指令中的
Duration
属性对应。
[PartialCaching(int duration, string varyByParams, string varyByControls, string varyByCustom)]
这种格式设置的内容较多。参数
duration
与上面说明的相同。参数
varyByParams
是一个由分号分隔的字符串列表,用于使输出缓存发生变化。该参数与
@ OutputCache
指令中的
VaryByParam
属性对应。参数
varyByControls
是一个由分号分隔的字符串列表,用于使输出缓存发生变化,其与
@ OutputCache
指令中的
VaryByControl
属性对应。参数
varyByCustom
用于设置任何表示自定义输出缓存要求的文本,与
@ OutputCache
指令中的
VaryByCustom
属性对应。
[PartialCaching(int duration, string varyByParams, string varyByControls, string varyByCustom, bool shared)]
这种格式中,参数
duration
、
varyByParams
、
varyByControls
、
varyByCustom
都与上面说明的参数相同。只有参数
shared
是新添加的。参数
shared
值是一个布尔值,用于确定用户控件输出缓存是否可以由多个页面共享。默认值为
false
。当该参数设置为
true
,表示用户控件输出缓存可以被多个页面共享,可以潜在节省大量内存。
[PartialCaching(int duration, string varyByParams, string varyByControls, string varyByCustom, string sqlDependency, bool shared)]
以上格式中添加了一个新参数
sqlDependency
。用于设置用户控件缓存入口所使用
SQL Server
缓存依赖功能的数据库及表名。如果包含多个数据库及表名,则使用分号(
;
)分隔开来。当该属性值发生变化时,缓存入口将过期。另外,数据库名必须与
web.config
文件中的
<sqlcachedependency>
配置节的内容匹配。
以上介绍了
PartialCachingAttribute
类的
6
个属性和
4
种构造函数。下面通过一个典型示例说明该类的具体应用方法。例如,使用
PartialCachingAttribute
类设置用户控件(
NewUserControl.ascx
文件)的缓存有效期时间是
20
秒,其代码如下所示。
使用PartialCachingAttribute类实现设置用户控件缓存
|
[PartialCaching(20)]
public partial class NewUserControl : UserControl
{......}
|
以上代码会存储在
NewUserControl.ascx.cs
文件中。
NewUserControl
是用户控件类,继承自
UserControl
基类。当使用
PartialCachingAttribute
类设置该用户控件缓存时,必须在控件类声明前设置
“[PartialCaching(......)]”
。该代码段可详细设置用户控件的缓存功能。例如,以上代码设置了缓存有效时间为
20
秒。这与在
NewUserControl.ascx
文件顶部设置
@ OutputCache
指令的
Duration
属性值为
20
是一致的。
由于用户控件应用了
PartialCachingAttribute
类(或者包含
@ OutputCache
指令),则
ASP.NET
分析器将生成
PartialCachingControl
类的实例来包装该用户控件。需要注意的是,此时生成
PartialCachingControl
类实例还有一个必要条件,即必须通过使用
TemplateControl.LoadControl
方法动态加载用户控件,并且,将用户控件插入页面的控件层次结构中,这样才会生成
PartialCachingControl
类实例。在通常情况下是不能直接使用
PartialCachingControl
类的。生成
PartialCachingControl
类实例能够在运行时,获取对用户控件缓存设置的更大灵活性。
12.3.3 使用ControlCachePolicy类
ControlCachePolicy
是
.NET Framework 2.0
中新出现的类,主要用于提供对用户控件的输出缓存设置的编程访问。
ControlCachePolicy
类与前文说明的
HttpCachePolicy
类有些类似。只是二者所访问的对象不同。
HttpCachePolicy
类用于访问页面输出缓存,而
ControlCachePolicy
类用于访问用户缓存。
使用
ControlCachePolicy
类有以下注意事项。
一是如果要创建正确有效的
ControlCachePolicy
类实例以便设置控件缓存,那么必须访问
PartialCachingControl
类的
BasePartialCachingControl.CachePolicy
属性(
BasePartialCachingControl
是
PartialCachingControl
类的基类)。在这个过程中,需要调用
LoadControl
方法,实现动态加载用户控件,这样才能获得为
PartialCachingControl
类包装的用户控件实例,进而利用其
CachePolicy
属性获取
ControlCachePolicy
实例。如果直接访问用户控件的
UserControl.CachePolicy
属性,则只能在该用户控件已由
BasePartialCachingControl
控件包装的情况下,才能获取有效的
ControlCachePolicy
实例。如果用户控件未进行包装,那么尝试通过
CachePolicy
属性获取
ControlCachePolicy
实例将引发异常,因为它不具有关联的
BasePartialCachingControl
。若要确定用户控件实例是否支持缓存(而不生成异常),可检查
SupportsCaching
属性。
二是
ControlCachePolicy
实例仅在控件生命周期的
Init
和
PreRender
阶段之间,才能成功操作。如果在
PreRender
阶段后修改
ControlCachePolicy
对象,则
ASP.NET
会引发异常,因为呈现控件后所进行的任何更改,都无法影响缓存设置(控件在
Render
阶段缓存)。以上内容说明最好在
Page_Init
事件处理程序中,创建并操作
ControlCachePolicy
实例。
下面首先讲解
ControlCachePolicy
类的
6
个属性,它们是
Cached
、
Dependency
、
Duration
、
SupportsCaching
、
VaryByControl
和
VaryByParams
。
Cached
属性
用于获取或者设置一个布尔值,表示是否在用户控件中启用控件缓存功能。
true
表示启用控件缓存功能,否则为
false
。
Dependency
属性
用于获取或者设置一个
CacheDependency
实例对象,该对象与用户控件的输出缓存关联。默认值为
null
。当
CacheDependency
实例对象失效时,用户控件的输出缓存将从缓存中移除。
Duration
属性
获取或者设置一个
TimeSpan
结构,表示用户控件输出缓存的有效时间。默认值为
Zero
。
SupportsCaching
属性
该属性获取一个布尔值,用于表示用户控件是否支持缓存功能。如果属性值为
true
,则表示该用户控件支持缓存;否则为
false
。
VaryByControl
属性
用于获取或者设置一个由分号分隔的字符串列表,这些字符串包含在用户控件中声明的服务器控件
ID
属性值。可根据该属性值,使输出缓存发生变化。
VaryByParams
属性
用于获取或者设置一个由分号分隔的字符串列表。默认情况下,这些字符串与用
GET
方法属性发送的查询字符串值对应,或与用
POST
方法发送的参数对应。用户控件可根据该属性值,使输出缓存发生变化。
另外,
ControlCachePolicy
类还包括
3
个常用方法,
SetExpires
、
SetSlidingExpiration
和
SetVaryByCustom
。
public void SetExpires(DateTime expirationTime);
指示用户控件输出缓存入口在特定的时间内过期。可使用
SetExpires
和参数设置为
true
的
SetSlidingExpiration
方法指示用户控件输出缓存使用可调过期策略。如果
SetSlidingExpiration
方法的参数设置为
false
,则用户控件输出缓存使用绝对过期策略。
public void SetSlidingExpiration(bool useSlidingExpiration);
指示用户控件缓存入口使用
Sliding
过期策略,或者
Absolute
过期策略。当参数
useSlidingExpiration
设置为
true
时,则用户控件输出缓存使用
Sliding
过期策略。否则,使用
Absolute
过期策略。
public void SetVaryByCustom(string varyByCustom);
用于自定义用户控件输出缓存使用的任意文本。如果该属性值是
browser
,用户控件输出缓存将随浏览器名称和主要版本信息的不同而不同。如果输入了自定义字符串,则必须在
Global.asax
文件中重写
HttpApplication.GetVaryByCustomString
方法。
下面介绍一个典型示例,动态设置用户控件缓存过期时间为
30
秒,并且使用绝对过期策略。用户控件代码隐藏文件源代码如下。
使用PartialCachingAttribute类实现设置用户控件缓存(用户控件代码隐藏文件)
|
[PartialCaching(100)]
public partial class SimpleControl : UserControl
{......}
|
如上代码所示,用户控件类名为
SimpleControl
,使用
PartialCachingAttribute
类设置默认的控件缓存过期时间为
100
秒。进行如此设置的目的是,实现使用
PartialCachingAttribute
类对用户控件类的包装,否则,在
ASP.NET
页面中调用
CachePolicy
属性获取的
ControlCachePolicy
实例是无效的。也可以采用其他方法对用户控件进行
PartialCachingAttribute
类包装,例如,设置
@ OutputCache
指令等。
下面列举
ASP.NET
页面文件源代码。
使用ControlCachePolicy类实现设置用户控件缓存(ASP.NET页面文件)
|
<%@ Page Language="C#" Debug="true" %>
<%@ Reference Control="SimpleControl.ascx" %>
<script language="C#" runat="server">
void Page_Init(object sender, System.EventArgs e)
{
// 动态加载用户控件,并返回PartialCachingControl的实例对象
PartialCachingControl pcc = LoadControl("SimpleControl.ascx") as PartialCachingControl;
// 通过CachePolicy属性获取ControlCachePolicy实例
ControlCachePolicy cacheSettings = pcc.CachePolicy;
// 如果用户控件的缓存过期设置大于60秒,则设置新的过期时间为30秒,并将其设置为绝对过期策略
if (cacheSettings.Duration > TimeSpan.FromSeconds(60))
{
// 设置用户控件过期时间和缓存过期策略
cacheSettings.SetExpires(DateTime.Now.Add(TimeSpan.FromSeconds(30)));
cacheSettings.SetSlidingExpiration(false);
}
// 将用户控件添加到页面控件层次结构中
Controls.Add(pcc);
}
</script>
|
以上代码是一个包含用户控件
SimpleControl.ascx
的
ASP.NET
文件源代码的一部分,主要以编程方式实现对用户控件输出缓存的设置。在整个实现过程中,由于需要设置用户控件缓存,因此,必须在
ASP.NET
页面的
Page_Init
事件处理程序中进行详细设置。首先,使用
TemplateControl.LoadControl
方法动态加载
SimpleControl..ascx
文件。由于用户控件
SimpleControl..ascx
已经为
PartialCachingAttribute
类包装(这一步很关键),因此,
LoadControl
方法的返回对象不是空引用,而是
PartialCachingControl
实例。然后,使用
PartialCachingControl
实例对象的
CachePolicy
属性,获取
ControlCachePolicy
实例对象。该对象主要用于设置用户控件输出缓存的设置。接着,使用
SetExpires
方法和参数为
false
的
SetSlidingExpiration
方法,设置用户控件输出缓存有效期为
30
秒,并且设置缓存使用绝对过期策略。最后,利用
Controls
类的
Add
方法将设置好的用户控件添加到页面控件层次结构中。另外,
@ Reference
指令用于对用户控件
SimpleControl.ascx
进行动态编译和链接。
12.3.4 实现缓存后替换
ASP.NET
页面中既包含静态内容,又包含基于数据库数据的动态内容。静态内容通常不会发生变化。因此,对静态内容实现数据缓存是非常必要的。然而,那些基于数据的动态内容,则不同。数据库中的数据可能每时每刻都发生变化,因此,如果对动态内容实现缓存,可能造成数据不能及时更新的问题。对此问题如果使用前文所述的控件缓存方法,显然不切实际,而且实现起来很繁琐,易于发生错误。
以上所述问题的本质是如何才能够实现缓存页面的大部分内容,而不缓存页面中的某些片段。
ASP.NET 2.0
提供了缓存后替换功能。实现该项功能可通过以下
3
种方法:一是以声明方式使用
Substitution
控件,二是以编程方式使用
Substitution
控件
API
,三是以隐式方式使用
AdRotator
控件。前两种方法的核心是
Substitution
控件,本节将重点介绍该控件,第三种方法仅专注于
AdRotator
控件内置支持的缓存后替换功能,本节仅做简要说明。
1.Substitution控件应用
为提高应用程序性能,可能会缓存整个
ASP.NET
页面,同时,可能需要根据每个请求来更新页面上特定的部分。例如,可能要缓存页面的很大一部分,需要动态更新该页上与时间或者用户高度相关的信息。在这种情况下,推荐使用
Substitution
控件。
Substitution
控件能够指定页面输出缓存中需要以动态内容替换该控件的部分,即允许对整页面进行输出缓存,然后,使用
Substitution
控件指定页中免于缓存的部分。需要缓存的区域只执行一次,然后从缓存读取,直至该缓存项到期或被清除。动态区域,也就是
Substitution
控件指定的部分,在每次请求页面时都执行。
Substitution
控件提供了一种缓存部分页面的简化解决方案。
Substitution
控件继承自
Control
基类,其声明代码如下所示:
Substitution控件声明代码
|
<asp:substitution id="Substitution1" methodname=" " runat="Server">
</asp:substitution>
|
如上代码所示,
Substitution
控件有一个重要属性
––––MethodName
属性。该属性用于获取或者设置当
Substitution
控件执行时为回调而调用的方法名称。该方法比较特殊,必须符合以下
3
条标准:此方法必须被定义为静态方法;此方法必须接受
HttpContext
类型的参数;此方法必须返回
String
类型的值。
在运行情况下,
Substitution
控件将自动调用
MethodName
属性所定义的方法。该方法返回的字符串即为要在页面中的
Substitution
控件的位置上显示的内容。如果页面设置了缓存全部输出,那么在第一次请求时,该页将运行并缓存其输出。对于后续的请求,将通过缓存来完成,该页上的代码不会运行。
Substitution
控件及其有关方法则在每次请求时都执行,并且自动更新该控件所表示的动态内容。
需要注意以下
3
点:一是
Substitution
控件无法访问页上的其他控件,也就是说,无法检查或更改其他控件的值。但是,代码确实可以使用传递给它的参数来访问当前页上下文。二是在缓存页包含的用户控件中可以包含
Substitution
控件。但是,在输出缓存用户控件中不能放置
Substitution
控件。三是
Substitution
控件不会呈现任何标记,其位置所显示内容完全取决于所定义方法的返回字符串。
下面列举了一个使用
Substitution
控件实现缓存后替换功能的示例。示例效果如图
12-3
所示。
图12-3 缓存后替换示例效果图
应用程序包括两个时间显示。第一个时间显示使用
Substitution
控件实现了缓存后替换功能,因此,每当单击
“
刷新页面
”
按钮,其显示的都是当前最新时间。第二个时间显示应用了页面输出缓存,因此,其显示时间仅当数据过期时才更新。
应用程序
Default.aspx
文件源代码如下所示。
Default.aspx文件源代码
|
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ OutputCache Duration="5" VaryByParam="None" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>示例12-2</title>
<link id="InstanceStyle" href="StyleSheet.css" type="text/css" rel="stylesheet" />
</head>
<script runat="server" language="C#">
public void Page_Load(object sender, System.EventArgs e)
{
CachedDateLabel.Text = DateTime.Now.ToString();
}
public static string GetCurrentDateTime(HttpContext context)
{
return DateTime.Now.ToString();
}
</script>
<body>
<form id="form1" runat="server">
<div>
<fieldset style="width: 320px">
<legend class="mainTitle">使用Substitution控件实现页面部分缓存</legend>
<br />
<div class="littleMainTitle">以下时间显示使用Substitution控件实现缓存后替换:</div>
<asp:Substitution ID="Substitution2" MethodName="GetCurrentDateTime" runat="Server"></asp:Substitution>
<hr />
<div class="littleMainTitle">以下时间显示使用页面输出缓存,缓存时间为5秒:</div>
<asp:Label ID="CachedDateLabel" runat="Server"></asp:Label>
<br />
<center>
<asp:Button ID="RefreshButton" Text="刷新页面
" runat="Server"></asp:Button></center>
</fieldset>
</div>
</form>
</body>
</html>
|
如上粗体代码所示,页面主要包括
Substitution
、
Label
和
Button
控件。在
Page_Load
事件处理程序中设置了
Label
控件显示时间值。另外,还实现了一个静态方法
GetCurrentDateTime
,该方法参数为
HttpContext
类型,返回值为
String
类型,其返回内容为当前时间。在代码顶部通过
@ OutputCache
指令设置页面输出缓存过期时间为
5
秒,这意味着整个页面数据都应用了缓存功能。因此,
Label
控件所显示的时间值来自于数据缓存。这个时间值不会随着刷新页面而变化,仅当数据过期时才会发生更新。
Substitution
控件的
MethodName
属性值为
GetCurrentDateTime
。该控件显示的内容来自于
GetCurrentDateTime
方法的返回值。尤为重要的是,虽然页面设置了输出缓存功能,但是每当页面刷新时,
ASP.NET
执行引擎仍然要重新执行
Substitution
控件,并将
MethodName
属性值指定的方法返回值显示在页面上,因此,显示的是当前时间值。
2.Substitution控件API应用
上一小节介绍了以声明方式使用
Substitution
控件实现缓存后替换的应用。本节仍然围绕实现缓存后替换功能,说明另一种实现方法。该方法的核心是以编程方式利用
Substitution
控件
API
实现缓存后替换,相对于以声明方式使用
Substitution
控件的方法具有更强灵活性。
Substitution
控件
API
包括一个关键的
WriteSubstitution
方法,该方法来自于
HttpResponse
类,其语法代码如下:
WriteSubstitution方法的语法
|
public void WriteSubstitution (HttpResponseSubstitutionCallback callback)
|
如上所示,
WriteSubstitution
方法仅有一个参数
HttpResponseSubstitutionCallback
。该参数是一个委托,其语法代码如下:
HttpResponseSubstitutionCallback委托的语法
|
public delegate string HttpResponseSubstitutionCallback (HttpContext context)
|
如上代码所示,
HttpResponseSubstitutionCallback
委托定义的方法有两个特征:一是返回值必须是
String
,二是参数有且仅有一个,并且是
HttpContext
类型。
以上介绍了
WriteSubstitution
方法及其参数的语法,这是使用
WriteSubstitution
方法实现缓存后替换的关键所在。
当需要以编程方式,为缓存的输出响应动态生成指定的响应区域时,可以在页面代码中将某个方法(即回调方法)的名称作为参数(
HttpResponseSubstitutionCallback
)传递给
WriteSubstitution
方法。这样
WriteSubstitution
方法就能够使用回调方法,并将回调方法的返回值作为给定位置的替代内容显示出来。在这个过程中,回调方法的声明是关键,不仅要采用单个
HttpContext
参数,而且必须返回一个字符串。需要注意的是,回调方法必须是线程安全的,可以是作为容器的页面或者用户控件中的静态方法,也可以是其他任意对象上的静态方法或实例方法。由此可见,使用
WriteSubstitution
方法的优点是可以调用任意对象的方法,而不只是调用
Page
或者
UserControl
对象的静态方法。
在第一次请求页面时,
WriteSubstitution
执行以下步骤:调用
HttpResponseSubstitutionCallback
委托以生成输出;向响应添加替换缓冲数据,该缓冲区将保留委托(以对将来的请求调用)以及步骤一中的首次输出;最后,将客户端缓存能力从
“
公共
”
降低到
“
仅服务器
”
,这样页面就不会在客户端进行缓存,确保以后对该页的请求将重新调用该委托,并生成动态内容。在后续请求时,缓存模块截获传入的请求并检索关联的存储缓冲区。在写入替换缓冲区时,调用该委托以生成新的输出,该输出被写入到响应中。
下面列举了一个
WriteSubstitution
方法的应用示例,与图
12-3
所示的示例完成同样功能。不同的是实现方式。前文示例使用的是
Substitution
控件,而此处使用的是
Substitution
控件
API
的
WriteSubstitution
方法。应用程序
Default.aspx
文件部分源代码如下:
Default.aspx文件部分源代码
|
<%@ OutputCache Duration="5" VaryByParam="None" %>
<head id="Head1" runat="server">
<title>示例12-3</title>
<link id="InstanceStyle" href="StyleSheet.css" type="text/css" rel="stylesheet" />
</head>
<script runat="server" language="C#">
......
public static string GetCurrentDateTime(HttpContext context)
{
return DateTime.Now.ToString();
}
</script>
<body>
<form id="form1" runat="server">
......
<div class="littleMainTitle">以下时间显示使用Substitution控件API实现缓存后替换:</div>
<% Response.WriteSubstitution(new HttpResponseSubstitutionCallback(GetCurrentDateTime)); %>
......
</form>
<body>
|
如上粗体代码所示,页面使用
@ OutputCache
指令设置了输出缓存功能,其配置数据缓存过期时间为
5
秒。然而,并非所有页面内容都被缓存,部分内容是不被缓存的。不参与缓存的内容是代码中通过调用
Response.WriteSubstitution
方法而获取并显示的返回字符串,显示了当前时间。需要注意的是,
Response.WriteSubstitution
方法的参数,该参数必须是
HttpResponseSubstitutionCallback
委托实例。本例中,委托所定义的方法是
GetCurrentDateTime
,该方法是一个静态方法,并且参数是
HttpContext
类型,返回值是
String
类型。
3.AdRotator控件的缓存后替换
AdRotator
是一个直接支持缓存替换功能的控件。如果将
AdRotator
控件放在页面上,则无论是否缓存父页,都将在每次请求时呈现其特有的广告。例如,如果页面包含静态内容(如新闻报道)和显示广告的
AdRotator
控件,这种情况下,此缓存模型就很有用。新闻报道不会更改,这意味着它们可以缓存。但是,应用程序要求在每次请求该页时都显示一条新广告。由于
AdRotator
控件直接支持缓存后替换,因此,无论页是否缓存,都在该页回发时呈现一个新广告。