-
您可以使用Substitution 控件,在網頁上建立可動態更新並可隨後整合到快取頁中的區域。
一、方案
使用Substitution 控制項可以在要快取輸出的網頁上指定要顯示動態內容的部分。對於多數內容都要進行快取的頁,Substitution 控制項提供了進行部分頁快取的簡化的解決方案。您可以快取整個頁的輸出,然後使用Substitution 控制項來指定頁中不進行快取的部分。快取區域僅執行一次,且將一直從快取讀取,直到該快取條目到期或被清除。動態區域則在每次請求頁時都會執行。此快取模型簡化了其內容主要是靜態內容的網頁的程式碼,因為您不必在Web 使用者控制項中對這些靜態內容進行封裝,以將它們放入快取。例如,對於包含靜態內容(如新聞故事)和顯示廣告的AdRotator 控制項的網頁,此快取模型非常有用。新聞故事不會經常更改,這意味著可以將它們放入快取。您可能會希望在使用者每次要求該網頁時顯示一則新廣告。 AdRotator 控制項直接支援快取後替換,無論是否快取了網頁,它都會在網頁每次回發時呈現一個新廣告。
二、背景
快取ASP.NET 網頁時,預設情況下,會快取該網頁的全部輸出。在第一次請求時,該頁將運行並快取其輸出。對於後續的請求,將透過快取來完成,該頁上的程式碼不會運行。
在某些情況下,您可能不但希望快取ASP.NET 網頁,也希望在每次要求該網頁時更新該網頁上的選定部分。例如,您可能想要快取某頁的很大一部分,但需要動態更新該頁上的與時間高度相關的資訊。
可以使用Substitution 控制項將動態內容插入到快取頁中。 Substitution 控制項不會呈現任何標記。因此,您需要將該控制項綁定到網頁或父級使用者控制項中的方法。您需要建立可傳回要插入網頁中的資訊的靜態方法。由Substitution 控制項呼叫的方法必須符合下面的標準:
·必須為靜態方法(在Visual Basic 共用)。
·必須接受類型為HttpContext 的參數。
·必須傳回類型為String 的值。
Substitution 控制項無法存取網頁上的其他控制項,也就是說,您無法檢查或變更其他控制項的值。但程式碼卻可使用傳遞給它的參數來存取目前網頁的上下文。
在頁面運行時,Substitution 控制項會呼叫該方法,然後用從該方法的回傳值取代頁上的Substitution 控制項。
程式碼範例
下面的範例示範如何使用Substitution 控制項在快取頁上建立可動態更新的內容。頁的Load 事件中的程式碼會用當前時間來更新Label 控制項。因為頁的快取持續時間已設定為60 秒,所以Label 控制項的文字不會更改,即使在60 秒的時間內多次要求了該頁。頁上的Substitution 控制項呼叫靜態方法GetTime,該方法將以字串的形式傳回目前時間。每次刷新網頁時,都會更新Substitution 控制項表示的值。
<%@ 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>
三、Substitution 類
使用Substitution 控制項指定輸出快取網頁上要以動態內容取代該控制項的部分。 Substitution 控制項為要快取大部分內容的頁面提供了一個快取局部頁的簡化解決方案。可以對整頁進行輸出緩存,然後使用Substitution 控制項指定頁中免於快取的部分。需要快取的區域只執行一次,然後從快取讀取,直到該快取項目到期或清除。動態區域則在每次請求頁時執行。由於不必對這些部分進行封裝以緩存在Web 使用者控制項中,因此,此快取模型簡化了主要是靜態內容的頁的程式碼。例如,如果頁包含靜態內容(如新聞報導)和顯示廣告的AdRotator 控件,在這種情況下,此快取模型就很有用。新聞報道不會更改,這意味著它們可以快取。但是,您希望在使用者每次要求該頁面時都顯示一則新廣告。 AdRotator 控制項直接支援快取後替換,無論頁是否緩存,都在該頁回發時呈現一個新廣告。
說明: 在快取頁包含的使用者控制項中可以放置Substitution 控制項。但是,在輸出快取使用者控制項中不能放置Substitution 控制項。
Substitution 控制項執行時,會呼叫一個傳回字串的方法。此方法傳回的字串即為要在頁中的Substitution 控制項的位置上顯示的內容。使用MethodName 屬性指定在Substitution 控制項執行時呼叫的回呼方法的名稱。指定的回呼方法必須是包含Substitution 控制項的頁或使用者控制項的靜態方法。回呼方法的簽章必須與接受HttpContext 參數並傳回字串的HttpResponseSubstitutionCallback 委託的簽章相符。
若要操作頁的輸出緩存,可使用@ OutputCache 指令、HttpCachePolicy 類別或Cache 屬性。
Substitution 控制項的另一種使用方法是,使用HttpResponseSubstitutionCallback 委託實作快取替換行為。此外,還可以在直接支援快取替換功能的控制項(如AdRotator 控制項)上實作快取替換行為。
範例
下面的程式碼範例示範如何以宣告方式將Substitution 控制項新增至輸出快取網頁。載入頁面時,將在一個標籤中向使用者顯示目前的日期和時間。頁面中的此區域僅60 秒便快取和更新一次。當Substitution 控制項執行時,將呼叫GetCurrentDateTime 方法。 GetCurrentDateTime 傳回的字串將顯示給使用者。每次刷新頁時,都不會快取和更新頁中的這一部分。
<%@ 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>