3 页面部分缓存

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 控件直接支持缓存后替换,因此,无论页是否缓存,都在该页回发时呈现一个新广告。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值