ASP.NET中的OutputCache指令
使用@ OutputCache指令
使用@ OutputCache指令,能夠?qū)崿F(xiàn)對頁面輸出緩存的一般性需要。@ OutputCache指令在asp.net頁或者頁中包含的用戶控件的頭部聲明。這種方式非常方便,只需幾個簡單的屬性設(shè)置,就能夠?qū)崿F(xiàn)頁面的輸出緩存 策略。@ OutputCache指令聲明代碼如下。
@ OutputCache指令代碼
- <%@ OutputCache CacheProfile =" " NoStore= "True | False" Duration ="#ofseconds" Shared ="True | False" Location ="Any | Client | Downstream | Server | None | ServerandClient " SqlDependency ="database/table name pair | CommandNotification " VaryByControl ="controlname" VaryByCustom ="browser | customstring" VaryByHeader ="headers" VaryByParam ="parametername" %>
如上所示,在@ OutputCache指令中,共包括10個屬性,它們是CacheProfile、NoStore、Duration、Shared、 Location、SqlDependency、VaryByControl、VaryByCustom、VaryByHeader和 VaryByParam。這些屬性將對緩存時間、緩存項的位置、SQL數(shù)據(jù)緩存依賴等各方面進(jìn)行設(shè)置。下面簡要介紹以上屬性的基本概念。
CacheProfile
用于定義與該頁關(guān)聯(lián)的緩存設(shè)置的名稱。是可選屬性,默認(rèn)值為空字符("")。需要注意的是,包含在用戶控件中的@ OutputCache指令不支持此屬性。在頁面中指定此屬性時,屬性值必須與Web.config文件<o(jì)utputCacheSettings>配置 節(jié)下的outputCacheProfiles元素中的一個可用項的名稱匹配。如果此名稱與配置文件項不匹配,將引發(fā)異常。
NoStore
該屬性定義一個布爾值,用于決定是否阻止敏感信息的二級存儲。需要注意的是,包含在用戶控件中的@ OutputCache指令不支持此屬性。將此屬性設(shè)置為true等效于在請求期間執(zhí)行代碼“Response.Cache.SetNoStore();”。
Duration
用于設(shè)置頁面或者用戶控件緩存的時間。單位是秒。通過設(shè)置該屬性,能夠為來自對象的HTTP響應(yīng)建立了一個過期策略,并將自動緩存頁或用戶控件輸出。需要注意的是,Duration屬性是必需的,否則將會引起分析器錯誤。
Shared
該屬性定義一個布爾值,用于確定用戶控件輸出是否可以由多個頁共享。默認(rèn)值為false。注意,包含在asp.net頁中的@ OutputCache指令不支持此屬性。
Location
用于指定輸出緩存項的位置。其屬性值是OutputCacheLocation枚舉值,它們是Any、Client、Downstream、None、 Server和ServerAndClient。默認(rèn)值是Any,表示輸出緩存可用于所有請求,包括客戶端瀏覽器、代理服務(wù)器或處理請求的服務(wù)器上。需要注意的是,包含在用戶控件中的@ OutputCache指令不支持此屬性。
SqlDependency
該屬性標(biāo)識一組數(shù)據(jù)庫/表名稱對的字符串值,頁或控件的輸出緩存依賴于這些名稱對。需要注意:SqlCacheDependency類監(jiān)視輸出緩存所依賴 的數(shù)據(jù)庫中的表,因此,當(dāng)更新表中的項時,使用基于表的輪詢將從緩存中移除這些項。當(dāng)通知(在SQL Server 2005中)與CommandNotification值一起使用時,最終將使用SqlDependency類向SQL Server 2005服務(wù)器注冊查詢通知。另外,SqlDependency屬性的CommandNotification值僅在asp.net頁中有效??丶荒軐?基于表的輪詢用于@ OutputCache指令。
VaryByControl
該屬性使用一個分號分隔的字符串列表來更改用戶控件的輸出緩存。這些字符串代表在用戶控件中聲明的asp.net服務(wù)器控件的ID屬性值。除非已經(jīng)包含了VaryByParam屬性,否則在@ OutputCache指令中,該屬性是必需的。
VaryByCustom
用于自定義輸出緩存要求的任意文本。如果賦予該屬性值是browser,緩存將隨瀏覽器名稱和主要版本信息的不同而異。如果輸入了自定義字符串,則必須在 應(yīng)用程序的Global.asax文件中重寫HttpApplication.GetVaryByCustomString方法。
VaryByHeader
該屬性中包含由分號分隔的HTTP標(biāo)頭列表,用于使輸出緩存發(fā)生變化。當(dāng)將該屬性設(shè)為多標(biāo)頭時,對于每個指定的標(biāo)頭,輸出緩存都包含一個請求文檔的不同版 本。VaryByHeader屬性在所有HTTP 1.1緩存中啟用緩存項,而不僅限于asp.net緩存。用戶控件中的@ OutputCache指令不支持此屬性。
VaryByParam
該屬性定義了一個分號分隔的字符串列表,用于使輸出緩存發(fā)生變化。默認(rèn)情況下,這些字符串與用GET方法屬性發(fā)送的查詢字符串值對應(yīng),或與用POST方法 發(fā)送的參數(shù)對應(yīng)。當(dāng)將該屬性設(shè)置為多參數(shù)時,對于每個指定的參數(shù),輸出緩存都包含一個請求文檔的不同版本。可能的值包括“none”、“*”和任何有效的 查詢字符串或POST參數(shù)名稱。值得注意的是,在輸出緩存asp.net頁時,該屬性是必需的。它對于用戶控件也是必需的,除非已經(jīng)在用戶控件的@ OutputCache指令中包含了VaryByControl屬性。如果沒有包含,則會發(fā)生分析器錯誤。如果不需要使緩存內(nèi)容隨任何指定參數(shù)發(fā)生變化, 則可將該值設(shè)為“none”。如果要使輸出緩存根據(jù)所有參數(shù)值發(fā)生變化,則將屬性設(shè)置為“*”。
下面列舉了兩個使用@OutputCache指令的示例代碼。
使用@ OutputCache的示例代碼1
- <%@ OutputCache Duration="100" VaryByParam="none"%>
以上示例是@ OutputCache指令的基本應(yīng)用,其指示頁面輸出緩存的有效期是100秒,并且頁面不隨任何GET或POST參數(shù)改變。在該頁仍被緩存時接收到的請求由緩存數(shù)據(jù)提供服務(wù)。經(jīng)過100秒后,將從緩存中移除該頁數(shù)據(jù),并隨后顯式處理下一個請求并再次緩存頁。
使用@ OutputCache的示例代碼2
- <%@ OutputCache Duration="100" VaryByParam="location;firstname" %>
以上@ OutputCache指令設(shè)置頁面輸出緩存的有效期是100秒,并且根據(jù)查詢字符串參數(shù)location或者firstname來設(shè)置輸出緩存。例如,假設(shè)客戶端請求是“http://localhost/default.aspx?location=beijing”,那么該頁面將被作為緩存處理。
使用頁面輸出緩存API
上文介紹了使用@ OutputCache指令實現(xiàn)對于輸出緩存的各項設(shè)置。這種方法簡單易行,深得開發(fā)人員青睞。另外,asp.net 2.0還從asp.net 1.x中繼承和擴展了一種使用輸出緩存API來編程設(shè)置頁面輸出緩存的方法。該方法的核心是調(diào)用System.Web.HttpCachePolicy。該類主要包含用于設(shè)置緩存特定的HTTP標(biāo)頭的方法和用于控制asp.net頁面輸出緩存的方法。與.NET Framework 1.x中的HttpCachePolicy類相比,.NET Framework 2.0中的HttpCachePolicy類得到了擴充和發(fā)展。主要是增加了一些重要方法,例如,SetOmitVarStar方法等。由于HttpCachePolicy類方法眾多,下面簡要說明一些常用方法。
SetExpires方法
用于設(shè)置緩存過期的絕對時間。它的參數(shù)是一個DataTime類的實例,表示過期的絕對時間。
SetLastModified方法
用于設(shè)置頁面的Last-Modified HTTP標(biāo)頭。Last-Modified HTTP標(biāo)頭表示頁面上次修改時間,緩存將依靠它來進(jìn)行計時。如果違反了緩存限制層次結(jié)構(gòu),此方法將失敗。該方法的參數(shù)是一個DataTime類的實例。
SetSlidingExpiration方法
該方法將緩存過期從絕對時間設(shè)置為可調(diào)時間。其參數(shù)是一個布爾值。當(dāng)參數(shù)為true時,Cache-Control HTTP標(biāo)頭將隨每個響應(yīng)而更新。此過期模式與相對于當(dāng)前時間將過期標(biāo)頭添加到所有輸出集的IIS配置選項相同。當(dāng)參數(shù)為false時,將保留該設(shè)置,且任何啟用可調(diào)整過期的嘗試都將靜態(tài)失敗。此方法不直接映射到HTTP標(biāo)頭。它由后續(xù)模塊或輔助請求來設(shè)置源服務(wù)器緩存策略。
SetOmitVaryStar方法
asp.net 2.0新增的方法。用于指定在按參數(shù)進(jìn)行區(qū)分時,響應(yīng)是否應(yīng)該包含vary:*標(biāo)頭。方法參數(shù)是一個布爾值,若要指示HttpCachePolicy不對其VaryByHeaders屬性使用*值,則為true;否則為false。
SetCacheability方法
用于設(shè)置頁面的Cache-Control HTTP標(biāo)頭。該標(biāo)頭用于控制在網(wǎng)絡(luò)上緩存文檔的方式。該方法有兩種重載方式,所不同的是參數(shù)。一種重載方法的參數(shù)是HttpCacheability枚舉值,包括NoCache、Private、Public、Server、ServerAndNoCache和ServerAndPrivate(有關(guān)這些枚舉值的定義,可參考MSDN)。另一種方法的參數(shù)有兩個,一個參數(shù)是HttpCacheability枚舉值,另一個參數(shù)是字符串,表示添加到標(biāo)頭的緩存控制擴展。需要注意的是,僅當(dāng)與Private或NoCache指令一起使用時,字段擴展名才有效。如果組合不兼容的指令和擴展,則此方法將引發(fā)無效參數(shù)異常。
下面舉例說明頁面緩存API的HttpCachePolicy類的使用方法。
HttpCachePolicy類示例源代碼
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
Response.Cache.SetExpires(DateTime.Parse("6:00:00PM"));
Response類的Cache屬性用于獲取頁面緩存策略。該屬性的數(shù)據(jù)類型是HttpCachePolicy??赏ㄟ^調(diào)用Response.Cache來獲取HttpCachePolicy實例,進(jìn)而實現(xiàn)對于當(dāng)前頁面輸出緩存的設(shè)置。如上代碼所示,第一行代碼表示輸出緩存時間是60秒,并且頁面不隨任何GET或POST參數(shù)改變,等同于“<%@ OutputCache Duration="60" VaryByParam="none" %>”。第二行代碼設(shè)置緩存過期的絕對時間是當(dāng)日下午6時整。
頁面輸出緩存應(yīng)用
以上兩小節(jié)分別介紹了使用@ OutputCache指令和API設(shè)置頁面輸出緩存功能的內(nèi)容。實際上,兩種方法各有優(yōu)點,使用@ OutputCache指令方法比較簡潔,但靈活性較差。使用API方法,能夠在運行時動態(tài)地修改緩存配置,處理更多的復(fù)雜需求。本節(jié)將利用這些知識,實現(xiàn)一個簡單的頁面輸出緩存應(yīng)用的示例,其中既涉及@ OutputCache指令應(yīng)用,又涉及頁面輸出緩存API。示例效果如圖1和圖2所示。
圖1 停止緩存的效果圖
圖2 執(zhí)行緩存的效果圖
如圖1所示,應(yīng)用程序初始顯示的是停止執(zhí)行緩存的時間。當(dāng)用戶刷新頁面(URL地址是http://localhost:5159/Code%2012-1/Default.aspx,其中5159是服務(wù)器臨時端口號)時,時間值將隨時變化,以便顯示當(dāng)前的最新時間。如圖2所示,單擊“緩存時間”超鏈接后,頁面重定向到http://localhost:5159/Code%2012-1/Default.aspx?location=beijing。這時,頁面顯示的時間被緩存,數(shù)據(jù)過期時間為5秒。如果不斷地刷新該頁,那么每隔5秒鐘時間值才變化一次。
本節(jié)示例存在兩個關(guān)鍵點。一是在運行時實現(xiàn)停止緩存,二是配置@ OutputCache指令。這兩點都已經(jīng)在應(yīng)用程序Default.aspx文件中予以實現(xiàn),下面列舉了該文件源代碼。
Default.aspx文件源代碼
- <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
- <%@ OutputCache Duration="5" VaryByParam="location" %>
- <!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">
- <script language="C# " runat="server">
- void Page_Load(object sender, EventArgs e)
- {
- //設(shè)置僅將緩存數(shù)據(jù)存儲在服務(wù)器上
- Response.Cache.SetCacheability(HttpCacheability.Server);
- string temp_location = Request.QueryString["location"];
- //如果location為空,則不緩存,否則根據(jù)@ OutputCache指令聲明執(zhí)行緩存
- if (temp_location == null)
- {
- //停止當(dāng)前響應(yīng)的所有服務(wù)器緩存
- Response.Cache.SetNoServerCaching();
- Label1.Text = "停止緩存的時間:" + DateTime.Now.ToString();
- }
- else
- {
- Label1.Text = "設(shè)置了緩存的時間:" + DateTime.Now.ToString();
- }
- }
- </script>
- <head id="Head1" runat="server">
- <title>示例12-1</title>
- <link id="InstanceStyle" href="StyleSheet.css" type="text/css" rel="stylesheet" />
- </head>
- <body>
- <form id="form1" runat="server">
- <div>
- <fieldset style="width: 240px">
- <legend class="mainTitle">設(shè)置頁面輸出緩存</legend>
- <br />
- <center><asp:Label ID="Label1" runat="server" CssClass="commonText"></asp:Label></center>
- <br />
- <a href="Default.aspx?location=beijing" class="littleMainTitle" >緩存時間</a><br />
- </fieldset>
- </div>
- </form>
- </body>
- </html>
如上粗體代碼所示,代碼頭部的@ OutputCache指令設(shè)置了Duration和VaryByParam屬性,其指示數(shù)據(jù)過期時間為5秒。同時,緩存根據(jù)參數(shù)location發(fā)生變化。另外,代碼還實現(xiàn)了Page_Load事件處理程序。在該程序中,首先,使用SetCacheability方法設(shè)置數(shù)據(jù)緩存必須存儲在服務(wù)器上,然后,獲取QueryString的location參數(shù)值,最后,根據(jù)location參數(shù)值進(jìn)行判斷。如果location參數(shù)值為空,則調(diào)用SetNoServerCaching方法停止當(dāng)前響應(yīng)的所有服務(wù)器緩存,并顯示當(dāng)前時間值。雖然@ OutputCache指令配置了頁面輸出緩存,但是,不會執(zhí)行頁面輸出緩存功能。如果location參數(shù)值不為空,則直接顯示當(dāng)前時間值。在這種情況下,將執(zhí)行@ OutputCache指令的配置內(nèi)容。
- < %@ OutputCache NoStore="True" Duration="15" Location="Any" VaryByControl="OC" VaryByCustom="browser" VaryByHeader="headers" VaryByParam="none" %>
【編輯推薦】