15.3 页面部分缓存
知识点讲解:光盘:视频\PPT讲解(知识点)\第15章\页面部分缓存.mp4
除了整页输出缓存外,ASP.NET还提供了页面部分缓存功能。页面部分缓存是指输出缓存页面的某些部分,而不是缓存整个页面内容。实现页面部分缓存有两种机制:一种是将页面中需要缓存的部分置于用户控件(.ascx文件)中,并且为用户控件设置缓存功能(包含用户控件的ASP.NET页面可设置缓存,也可不设置缓存)。这就是通常所说的“控件缓存”。设置控件缓存的实质是对用户控件进行缓存配置。主要包括以下3种方法:一是使用@ OutputCache指令以声明方式为用户控件设置缓存功能;二是在代码隐藏文件中使用PartialCachingAttribute类设置用户控件缓存;三是使用ControlCachePolicy类以编程方式指定用户控件缓存设置。另外,还有一种称为“缓存后替换”的方法。该方法与控件缓存正好相反,将页面中的某一部分设置为不缓存。因此,尽管缓存了整个页面,但是当再次请求该页时,将重新处理那些没有设置为缓存的内容。
15.3.1 使用@ OutputCache指令
控件缓存与整页输出缓存的@ OutputCache指令既有相似之处,又有不同之处。二者的共同点在于它们的设置方法基本相同,都是文件顶部设置包含属性的@ OutputCache指令字符串。不同之处在以下两个方面:一是控件缓存的@ OutputCache指令设置在用户控件文件中,而整页输出缓存的@ OutputCache设置在普通ASP.NET文件中。二是控件缓存的@ Output Cache指令只能设置6个属性,即Duration、Shared、SqlDependency、VaryByControl、VaryByCustom和VaryByParam。而整页输出缓存的@ OutputCache指令字符串中设置的属性多达10个。
例如下面的代码。
<%@ OutputCache Duration="100" VaryByParam="CategoryID;SelectedID"%>
在上述代码中,设置了用户控件缓存的有效期时间是100秒,并且允许使用CategoryID和SelectedID参数来改变缓存。通过VaryByParam属性设置在服务器缓存中可能存储多个用户控件的实例。例如,对于一个包含用户控件的页面,可能存在如下的URL链接。
http://localhost/page.aspx?categoryid=foo&selectedid=1
http://localhost/page.aspx?categoryid=foo&selectedid=2
当请求如上URL地址的页面时,由于控件中@ OutputCache指令的设置,尤其是属性VaryByParam的设置,那么在服务器缓存中就会存储两个版本的用户控件缓存实例。
控件缓存设置除了支持以上所述的VaryByParam属性外,还支持VaryByControl属性。Vary ByParam属性基于使用POST或者GET方式发送的名称/值对来改变缓存,而VaryByControl属性通过用户控件文件中包含的服务器控件来改变缓存。例如,在下面的代码中,使用了VaryByControl属性。
<%@ OutputCache Duration="100" VaryByParam="none" VaryByControl="Category" %>
在上述代码中,设置缓存有效期为100秒,并且页面不随任何GET或POST参数改变(即使不使用VaryByParam属性,但是仍然需要在@ OutputControl指令中显式声明该属性)。如果用户控件中包含ID属性为“Category”的服务器控件(例如下拉列表框控件),则缓存将根据该控件的变化来存储用户控件数据。
15.3.2 使用PartialCachingAttribute类
除了使用@ OutputCache指令外,还可以使用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>配置节中的内容匹配。
15.3.3 使用ControlCachePolicy类
ControlCachePolicy类是从.NET Framework 2.0中开始出现的类,主要用于提供对用户控件的输出缓存设置的编程访问。ControlCachePolicy类与前文介绍的HttpCachePolicy类有些类似,唯一的区别是二者所访问的对象不同。其中,HttpCachePolicy类用于访问页面输出缓存,而ControlCachePolicy类用于访问用户缓存。
在使用ControlCachePolicy类时,需要注意如下2点。
(1)如果要创建正确有效的ControlCachePolicy类实例,以便设置控件缓存,则必须访问PartialCachingControl类的BasePartialCachingControl.CachePolicy属性(BasePartialCachingControl是PartialCachingControl类的基类)。
在上述过程中,需要调用LoadControl方法,实现动态加载用户控件,这样才能获得为PartialCachingControl类包装的用户控件实例,进而利用其CachePolicy属性获取ControlCache Policy实例。如果直接访问用户控件的UserControl.CachePolicy属性,则只能在该用户控件已由BasePartialCachingControl控件包装的情况下,才能获取有效的ControlCachePolicy实例。如果用户控件未进行包装,那么尝试通过CachePolicy属性获取ControlCachePolicy实例将引发异常,因为它不具有关联的BasePartialCachingControl控件。若要确定用户控件实例是否支持缓存(而不生成异常),可检查SupportsCaching属性。
(2)ControlCachePolicy实例仅在控件生命周期的Init和PreRender阶段之间才能成功操作。如果在PreRender阶段后修改ControlCachePolicy对象,则ASP.NET会引发异常,因为呈现控件后所进行的任何更改,都无法影响缓存设置(控件在Render阶段缓存)。上述内容说明最好在Page_Init事件处理程序中,创建并操作ControlCachePolicy实例。
ControlCachePolicy类中包括6个常用属性和3个常用方法,其中6个常用属性的具体说明如下。
- Cached属性
该属性用于获取或者设置一个布尔值,表示是否在用户控件中启用控件缓存功能。该属性值如果为True,表示启用控件缓存功能;否则为False。
- Dependency属性
该属性用于获取或者设置一个CacheDependency实例对象,该对象与用户控件的输出缓存关联。默认值为Null。当CacheDependency实例对象失效时,用户控件的输出缓存将从缓存中移除。
- Duration属性
该属性用于获取或者设置一个TimeSpan结构,表示用户控件输出缓存的有效时间。默认值为Zero。
- SupportsCaching属性
该属性用于获取一个布尔值,表示用户控件是否支持缓存功能。该属性值如果为True,表示该用户控件支持缓存;否则为False。
- VaryByControl属性
该属性用于获取或者设置一个由分号分隔的字符串列表,在用户控件声明的服务器控件中,在ID属性值中包含这些字符串在用户控件中声明的服务器控件ID属性值。可根据该属性值,使输出缓存发生变化。
- VaryByParams属性
该属性用于获取或者设置一个由分号分隔的字符串列表。默认情况下,这些字符串与用GET方法发送的查询字符串值对应,或与用POST方法发送的参数对应。用户控件可根据该属性值,使输出缓存发生变化。
3个常用方法的具体说明如下。
- public void SetExpires(DateTime expirationTime)
该方法用于设置用户控件输出缓存入口在特定的时间内过期。可使用SetExpires和参数设置为True的SetSlidingExpiration方法指示用户控件输出缓存使用可调过期策略。如果SetSliding Expiration方法的参数设置为False,则用户控件输出缓存使用绝对过期策略。
- public void SetSlidingExpiration(bool useSlidingExpiration)
该方法用于设置用户控件缓存入口使用Sliding过期策略,或者Absolute过期策略。如果参数useSlidingExpiration设置为True,则用户控件输出缓存使用Sliding过期策略;否则使用Absolute过期策略。
- public void SetVaryByCustom(string varyByCustom)
该方法用于自定义用户控件输出缓存使用的任意文本。如果该属性值是browser,则用户控件输出缓存将随浏览器名称和主要版本信息的不同而不同。如果输入了自定义字符串,则必须在Global.asax文件中重写HttpApplication.GetVaryByCustomString方法。
15.3.4 缓存后替换
ASP.NET页面中既包含静态内容,又包含基于数据库中数据的动态内容。静态内容通常不会发生变化。所以说,对静态内容实现数据缓存是非常必要的。然而对于那些基于数据库中数据的动态内容,则是不同的。数据库中的数据可能每时每刻都发生变化,因此,如果对动态内容实现缓存,可能造成数据不能及时更新。解决此问题如果使用前文所述的控件缓存方法显然不切实际,而且实现起来很繁琐,易于发生错误。
解决上述问题的本质是如何能够实现缓存页面的大部分内容,而不缓存页面中的某些片段。ASP.NET 中提供了缓存后替换功能。实现该项功能可通过以下3种方法。
- 以声明方式使用Substitution控件。
- 以编程方式使用Substitution控件API。
- 以隐式方式使用AdRotator控件。
其中,前两种方法的核心是Substitution控件,本节将重点介绍该控件;第三种方法仅专注于AdRotator控件内置支持的缓存后替换功能,本节仅做简要说明。
1.Substitution控件方法
为提高应用程序性能,可能会缓存全部ASP.NET页面,同时,可能需要根据每个请求来更新页面中特定的部分。例如,可能要缓存页面的很大一部分,另外需要动态更新该页上与时间或者用户高度相关的信息。在这种情况下,推荐使用Substitution控件。Substitution控件能够指定页面输出缓存中需要以动态内容替换该控件的部分,即允许对整页面进行输出缓存,然后使用Substitution控件指定页面中免于缓存的部分。需要缓存的区域只执行一次,然后从缓存读取,直至该缓存项到期或被清除。动态区域,也就是Substitution控件指定的部分,在每次请求页面时都执行。Substitution控件提供了一种缓存部分页面的简化解决方案。
Substitution控件继承Control基类,其声明格式如下。
<asp:substitution id="Substitution1" methodname=" " runat="Server">
</asp:substitution>
在上述格式中,MethodName属性用于获取或者设置当Substitution控件执行时的回调方法的名称。该方法比较特殊,使用时必须遵循以下3条原则。
- 必须被定义为静态方法。
- 必须接受HttpContext类型的参数。
- 必须返回String类型的值。
在运行情况下,Substitution控件将自动调用MethodName属性所定义的方法。该方法返回的字符串即为要在页面中的Substitution控件的位置上显示的内容。如果页面设置了缓存全部输出,那么在第一次请求时,该页将运行并缓存其输出。对于后续的请求,将通过缓存来完成,该页上的代码不会运行。Substitution控件及其有关方法则在每次请求时都执行,并且自动更新该控件所表示的动态内容。
在使用Substitution控件时,需要注意以下3点。
- Substitution控件无法访问页上的其他控件。也就是说,无法检查或更改其他控件的值。但是,代码确实可以使用传递给它的参数来访问当前页的上下文。
- 在缓存页包含的用户控件中可以包含Substitution控件,但在输出缓存用户控件中不能放置Substitution控件。
- Substitution控件不会呈现任何标记,其位置所显示内容完全取决于所定义方法的返回字符串。
实例073 使用Substitution控件实现缓存后替换
源码路径 光盘\daima\15\Web 视频路径 光盘\视频\实例\第15章\073
本实例的实现文件是kongjian.aspx,具体实现代码如下。
<%@ Page Language="C#|" %>
<%@ OutputCache Duration="60" 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> </title>
</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>
范例145:文本长度控制
源码路径:光盘\演练范例\145
视频路径:光盘\演练范例\145
范例146:文本换行
源码路径:光盘\演练范例\146
视频路径:光盘\演练范例\146
在上述实例代码中,应用程序包括两个时间显示。第一个时间显示使用Substitution控件实现了缓存后替换功能,因此,每次单击【刷新页面】按钮,其显示的都是当前最新时间,如图15-5所示;第二个时间显示应用了页面输出缓存,因此,其显示时间仅当数据过期时才更新,如图15-6所示。
图15-5 初始显示效果
图15-6 刷新后效果
2.Substitution控件API方法
该方法的核心是以编程方式利用Substitution控件API实现缓存后替换,相对于以声明方式使用Substitution控件的方法具有更强的灵活性。
Substitution控件API包含了一个关键的WriteSubstitution方法,该方法来自于HttpResponse类,其语法格式如下。
public void WriteSubstitution (HttpResponseSubstitutionCallback callback)
在上述语法格式中,WriteSubstitution方法只有一个参数HttpResponseSubstitutionCallback。该参数是一个委托类型,具体语法格式如下。
public delegate string HttpResponseSubstitutionCallback (HttpContext context)
在上述语法格式中,HttpResponseSubstitutionCallback委托定义的方法有如下两个特点:
- 返回值必须是String。
- 参数有且仅有一个,并且是HttpContext类型。
实例074 使用@ OutputCache指令设置输出缓存
源码路径 光盘\daima\15\Web 视频路径 光盘\视频\实例\第15章\074
本实例的实现文件是SubstitutionAPI.aspx,其主要实现代码如下所示。
<%@ Page Language="C#|" %>
<%@ OutputCache Duration="50" VaryByParam="None" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>示例12-2</title>
</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(GetCurrent DateTime)); %>
</form>
</body>
</html>
范例147:主外键表数据显示
源码路径:光盘\演练范例\147视频路径:光盘\演练范例\147范例148:将数据导入Excel
源码路径:光盘\演练范例\148视频路径:光盘\演练范例\148\
在上述实例代码中,使用@ OutputCache指令设置输出缓存功能,其配置数据缓存过期时间为50秒。然而,并非所有页面内容都被缓存,部分内容是不被缓存的。不参与缓存的内容是代码中通过调用Response.WriteSubstitution方法而获取并显示的返回字符串,显示了当前时间。需要注意的是Response.WriteSubstitution方法的参数,该参数必须是HttpResponseSubstitution Callback委托实例。本例中,委托所定义的方法是GetCurrentDateTime,该方法是一个静态方法,并且参数是HttpContext类型,返回值是String类型。实例执行后的界面效果如图15-7所示。
图15-7 执行效果
3.AdRotator控件的缓存后替换
AdRotator控件是一个直接支持缓存替换功能的控件。如果将AdRotator控件放置在页面上,则无论是否缓存父页,都将在每次请求时呈现其特有的广告。例如,如果页面包含静态内容(如新闻报道)和显示广告的AdRotator控件,这种情况下,此缓存模型就很有用。新闻报道不会更改,这意味着它可以缓存。但是,应用程序要求在每次请求该页时都显示一条新广告。由于AdRotator控件直接支持缓存后替换,因此,无论页面是否缓存,都在该页回发时呈现一个新广告。
共有条评论 网友评论