天天看點

ASP.NET 2.0的頁面緩存功能介紹

文章來自:http://www.sudu.cn/info/article/articleInfo.php?aId=318520

頁面部分緩存是指輸出緩存頁面的某些部分,而不是緩存整個頁面内容。實作頁面部分緩存有兩種機制:一種是将頁面中需要緩存的部分置于使用者控件(.ascx檔案)中,并且為使用者控件設定緩存功能(包含使用者控件的ASP.NET頁面可設定也可不設定緩存)。這就是通常所說的“控件緩存”。設定控件緩存的實質是對使用者控件進行緩存設定。主要包括以下3種方法:一是使用@ OutputCache指令以聲明方式為使用者控件設定緩存功能,二是在代碼隐藏檔案中使用PartialCachingAttribute類設定使用者控件緩存;三是使用ControlCachePolicy類以程式設計方式指定使用者控件緩存設定。另外,更有一種稱為“緩存後替換”的方法。該方法和控件緩存正好相反,将頁面中的某一部分設定為不緩存,是以,盡管緩存了整個頁面,不過當再次請求該頁時,将重新處理那些沒有設定為緩存的内容。

  使用@ 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指令設定了緩存,那麼緩存該怎麼運作呢?

  遇見這個問題時,應掌控以下個基本原則:一是ASP.NET允許在頁面和頁面的使用者控件中同時使用@ OutputCache指令設定緩存,并且允許設定不同的緩存過期時間值。二是如果頁面輸出緩存過期時間長于使用者控件輸出緩存過期時間,則頁面的輸出緩存持續時間優先。例如,如果頁面輸出緩存設定為100秒,而使用者控件的輸出緩存設定為50秒,則包括使用者控件在内的整個頁将在輸出緩存中存儲100秒,而和使用者控件較短的時間設定無關。三是如果頁面輸出緩存過期時間比使用者控件的輸出緩存過期時間短,則即使已為某個請求重新生成該頁面的其餘部分,也将一直緩存使用者控件直到其過期時間到期為止。例如,如果頁面輸出緩存設定為50秒,而使用者控件輸出緩存設定為100秒,則頁面其餘部分每到期兩次,使用者控件才到期一次。

  使用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檔案頂部設定指令的Duration屬性值為20是一緻的。

  由于使用者控件應用了PartialCachingAttribute類(或包含@ OutputCache指令),則ASP.NET分析器将生成PartialCachingControl類的執行個體來包裝該使用者控件。需要注意的是,此時生成PartialCachingControl類執行個體更有一個必要條件,即必須通過使用TemplateControl.LoadControl方法動态加載使用者控件,并且,将使用者控件插入頁面的控件層次結構中,這樣才會生成PartialCachingControl類執行個體。在通常情況下是不能直接使用PartialCachingControl類的。生成PartialCachingControl類執行個體能夠在運作時,擷取對使用者控件緩存設定的更大靈活性。

  使用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);

  訓示使用者控件輸出緩存入口在特定的時間内過期。可使用和參數設定為的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進行動态編譯和連結。

  實作緩存後替換

  ASP.NET頁面中既包含靜态内容,又包含基于資料庫資料的動态内容。靜态内容通常不會發生變化。是以,對靜态内容實作資料緩存是非常必要的。然而,那些基于資料的動态内容,則不同。資料庫中的資料可能每時每刻都發生變化,是以,如果對動态内容實作緩存,可能造成資料不能及時更新的問題。對此問題如果使用前文所述的控件緩存方法,顯然不切實際,而且實作起來非常繁瑣,易于發生錯誤。

  以上所述問題的本質是怎麼才能夠實作緩存頁面的大部分内容,而不緩存頁面中的某些片段。ASP.NET 2.0提供了緩存後替換功能。實作該項功能可通過以下三種方法:一是以聲明方式使用Substitution控件,二是以程式設計方式使用Substitution控件API,三是以隐式方式使用控件。前兩種方法的核心是Substitution控件,本節将重點介紹該控件,第三種方法僅專注于控件内置支援的緩存後替換功能,本節僅做簡要說明。

  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控件實作緩存後替換功能的示例。示例效果如圖3所示。

ASP.NET 2.0的頁面緩存功能介紹

圖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" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" 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>

<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委托以生成輸出;向響應添加替換緩沖資料,該緩沖區将保留委托(以對将來的請求調用)及步驟一中的首次輸出;最後,将用戶端緩存能力從“公共”降?????? ?o??低到“僅伺服器”,這樣頁面就不會在用戶端進行緩存,確定以後對該頁的請求将重新調用該委托,并生成動态内容。在後續請求時,緩存子產品截獲傳入的請求并檢索關聯的存儲緩沖區。在寫入替換緩沖區時,調用該委托以生成新的輸出,該輸出被寫入到響應中。

  下面列舉了一個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" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" 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類型。

  AdRotator控件的緩存後替換

  是個直接支援緩存替換功能的控件。如果将控件放在頁面上,則無論是否緩存父頁,都将在每次請求時呈現其特有的廣告。例如,如果頁面包含靜态内容(如新聞報道)和顯示廣告的控件,這種情況下,此緩存模型就非常有用。新聞報道不會更改,這意味着他們能緩存。不過,應用程式需求在每次請求該頁時都顯示一條新廣告。由于控件直接支援緩存後替換,是以,無論頁是否緩存,都在該頁回發時呈現一個新廣告。