ASP.NET 狀態管理建議事項
更新:2007 年 11 月
狀態管理是您用來對相同或不同網頁的多個要求,維護狀態和網頁資訊的處理序。就如同任何 HTTP 架構技術一樣,Web Form 網頁是沒有狀態的,這表示它們不會自動指出序列中的要求是否全都來自相同用戶端,也不會自動指出某個瀏覽器執行個體是否仍在主動檢視網頁或網站。除此之外,每次來回伺服器就會毀棄並重新建立網頁,因此網頁資訊隨著單一網頁的生命週期結束就不會存在。如需伺服器來回和 Web Form 網頁生命週期的詳細資訊,請參閱 ASP.NET 網頁存留週期概觀。
ASP.NET 提供了多種在伺服器往返之間維護狀態的方法。您應該選擇哪些選項,完全視您的應用程式而定,並且應該根據下列準則:
您需要儲存多少資訊?
用戶端是否接受永續性或記憶體中的 Cookie?
您想要在用戶端或是伺服器上儲存資訊?
這些資訊是否敏感?
您的應用程式具有何種效能與頻寬標準?
您所針對的瀏覽器和裝置功能為何?
您需要儲存每個使用者的資訊?
資訊需要儲存多久?
您是否擁有 Web 伺服陣列 (多重伺服器)、Web 處理序區 (單一電腦上有多重處理序)、或是服務應用程式的單一處理序?
用戶端狀態管理選項
使用用戶端選項儲存網頁資訊並不會用到伺服器資源。這些選項的安全性通常較低,而伺服器效能卻很快速,因為對伺服器資源的需求不是太大。但是,因為您必須將資訊傳送到用戶端以進行儲存,所以您能以這種方式儲存多少資訊實際上是有限制的。
下列是 ASP.NET 支援的用戶端狀態管理選項:
檢視狀態
控制項狀態
隱藏欄位
Cookie
查詢字串
檢視狀態
Web Form 網頁提供了 ViewState 屬性,做為對同一網頁的多個要求之間自動保留值的內建結構。檢視狀態在網頁中,是當做隱藏欄位進行維護。如需詳細資訊,請參閱 ASP.NET 狀態管理概觀。
您可以使用檢視狀態在網頁回傳給它自己的往返行程中,儲存您自己的網頁專用值。例如,如果您的應用程式要維護使用者專屬的資訊 (也就是網頁中使用的資訊,但未必是任何控制項的一部分),您可以將它儲存在檢視狀態中。
使用檢視狀態的優點包括:
不需要伺服器資源 檢視狀態包含在頁面程式碼的結構中。
實作簡單 檢視狀態不需要使用任何自訂程式設計。預設會啟用它來維護控制項的狀態資料。
增強安全性功能 檢視狀態中的值會經過雜湊、壓縮,並且針對 Unicode 實作編碼,提供比使用隱藏檔案更高的安全性。
使用檢視狀態的缺點包括:
效能考量 因為檢視狀態是儲存在網頁本身,如果儲存大量的值,可能會在使用者顯示網頁或張貼網頁時降低網頁速度。特別是與頻寬通常會受到限制的行動裝置有關。
裝置限制 行動裝置可能沒有足夠的記憶體容量,儲存大量的檢視狀態資料。
潛在安全性風險 檢視狀態會儲存在頁面的一個或多個隱藏欄位中。雖然檢視狀態是以雜湊的格式儲存資料,它仍然可以被竄改。如果直接檢視網頁的輸出來源,隱藏欄位中的資訊就可能會被看見,因此也造成了潛在的安全性問題。如需詳細資訊,請參閱 ASP.NET Web 應用程式安全性和 Web 應用程式的基本安全性實行方式。
控制項狀態
ASP.NET Web 網頁架構提供 ControlState 屬性,用以儲存伺服器來回往返之間的自訂控制項資料。例如,如果您撰寫擁有可以顯示不同資訊之索引標籤的自訂控制項,為了讓該控制項如預期般發揮作用,控制項需要知道在來回往返之間所選取的索引標籤。檢視狀態可以用以達到這個目的,但是開發人員可以在頁面層級關閉檢視狀態,就能有效破除您的控制。控制項狀態不像檢視狀態可以關閉,所以提供更可靠的方法儲存控制項狀態資料。
使用控制項狀態的優點包括:
不需要伺服器資源 根據預設,控制項狀態儲存在頁面的隱藏欄位中。
可靠性 因為控制項狀態不像檢視狀態能夠關閉,所以控制項狀態在管理控制項的狀態方面是更可靠的方法。
全面性 自訂配接器可以撰寫成控制儲存控制項狀態資料的方法及位置。
使用控制項狀態的缺點包括:
- 需要部分程式設計工作 儘管 ASP.NET Web 網頁架構提供控制項狀態的基礎,控制項狀態卻是一種自訂狀態保存的機制。若要完整利用控制項狀態,您必須撰寫程式碼儲存和載入控制項狀態。
隱藏欄位
您可以在網頁上的隱藏欄位中儲存網頁專屬資訊,做為維護網頁狀態的一種方式。如需隱藏欄位的詳細資訊,請參閱 ASP.NET 狀態管理建議事項。
如果您要使用隱藏欄位,最好在用戶端上只儲存少量、經常變更的資料。
注意事項: |
---|
如果您使用隱藏欄位,您必須使用 HTTP POST 方法將網頁送出至伺服器,而不要透過網頁 URL 要求網頁 (HTTP GET 方法)。 |
使用隱藏欄位的優點包括:
不需要伺服器資源 隱藏欄位是從網頁儲存和讀取。
廣泛支援 幾乎所有瀏覽器和用戶端裝置都支援具有隱藏欄位的表單。
簡單實作 隱藏欄位是標準 HTML 控制項,不需要複雜的程式設計邏輯。
使用隱藏欄位的缺點包括:
潛在安全性風險 隱藏欄位可能會遭他人竄改。如果直接檢視網頁的輸出來源,隱藏欄位中的資訊就可能會被看見,因此也造成了潛在的安全性問題。您可以手動加密或解密隱藏欄位的內容,但是這需要另外進行程式設計並且會造成額外負荷。如果安全性是一個考量,請考慮使用伺服器狀態機制,就不會將敏感資訊傳送至用戶端。如需詳細資訊,請參閱 ASP.NET Web 應用程式安全性和 Web 應用程式的基本安全性實行方式。
簡單的儲存架構 隱藏欄位不支援豐富型資料型別。隱藏欄位提供單一字串值欄位用以放置資訊。若要儲存多個值,您必須實作分隔的字串和剖析這些字串的程式碼。您可以手動從隱藏欄位,分別地將豐富型資料型別序列化和還原序列化。但是,這需要額外的程式碼才能做到。如果您要在用戶端儲存豐富型資料型別,請考慮改用檢視狀態。檢視狀態有內建序列化,並且會將資料儲存在隱藏欄位。
效能考量 因為隱藏欄位是儲存在網頁本身,如果儲存大量的值,可能會在使用者顯示網頁或張貼網頁時降低網頁速度。
儲存限制 如果隱藏欄位中的資料量變得很大,某些 Proxy 和防火牆會防止存取包含這些資料的網頁。因為最大資料量可能會因不同的防火牆和 Proxy 實作而有所不同,所以大型隱藏欄位可能有偶發性的問題。如果您需要儲存許多資料項目,請考慮執行下列其中一個步驟:
將每個項目放在不同的隱藏欄位中。
在開啟檢視狀態區塊化的情況下使用檢視狀態,其會自動將資料分隔到多個隱藏欄位中。
將資料保存在伺服器而不是用戶端。傳送至用戶端的資料越多,應用程式的表面回應時間就會越長,因為瀏覽器需要下載或傳送更多資料。
Cookie
Cookie 對於在用戶端上儲存少量、經常變更的資訊時很有用。這些資訊會隨著要求一起傳送到伺服器。如需建立和讀取 Cookie 的詳細資訊,請參閱 ASP.NET Cookie 概觀。
使用 Cookie 的優點包括:
可設定的到期規則 Cookie 可以在瀏覽器工作階段結束時到期,也可以依照用戶端的到期規則,無限期地存留在用戶端電腦上。
不需要伺服器資源 Cookie 會儲存在用戶端,並且伺服器會在每次張貼後讀取。
簡化 Cookie 具有簡單索引鍵值配對的輕量型文字結構。
資料保存性 雖然 Cookie 在用戶端電腦上的耐久性,是受到用戶端的 Cookie 過期處理序和使用者介入所影響,但是 Cookie 通常是用戶端在資料保存性上最耐久的格式。
使用 Cookie 的缺點包括:
大小限制 雖然越來越多新版的瀏覽器和用戶端裝置版本都支援 8192 個位元組的 Cookie,但是大部分的瀏覽器會將 Cookie 的大小限制在 4096 個位元組。
使用者設定的拒絕 有些使用者會停用瀏覽器或用戶端裝置接收 Cookie 的功能,因此會限制這項功能。
潛在安全性風險 Cookie 可能會遭他人竄改。使用者可在電腦上管理 Cookie,這樣就可能造成安全性的風險,或是導致依賴 Cookie 的應用程式執行失敗。此外,雖然只有將 Cookie 傳送到用戶端的網域才能夠存取它,但是駭客過去曾經找到從其他網域存取使用者電腦 Cookie 的方法。您可以手動加密或解密 Cookie,但是這需要另外進行程式設計並且會影響應用程式效能,因為加密和解密需要時間。如需詳細資訊,請參閱 ASP.NET Web 應用程式安全性和 Web 應用程式的基本安全性實行方式。
注意事項: Cookie 通常是進行個人化設定之用,其中內容會為已知的使用者自訂。在大部分的情況中,識別才是問題所在,而非驗證。因此,您通常可以將使用者名稱、帳戶名稱或唯一的使用者 ID (例如 GUID) 儲存在 Cookie 中,然後使用 Cookie 存取站台的使用者個人化基礎結構,以保護用來識別的 Cookie。
查詢字串
查詢字串是附加在網頁 URL 結尾的資訊。如需詳細資訊,請參閱 ASP.NET 狀態管理概觀。
您可以使用查詢字串將資料送回到您的網頁,或者透過 URL 送至另一網頁。查詢字串提供簡單但功能受限的方式來維護某些狀態資訊。例如,它們可以很輕易地將資訊從一個網頁傳遞到另一個網頁 (例如將產品編號傳遞到另一個處理這些編號的網頁)。
使用查詢字串的優點包括:
不需要伺服器資源 查詢字串包含在特定 URL 的 HTTP 要求中。
廣泛支援 幾乎所有的瀏覽器和用戶端裝置都支援使用查詢字串傳遞數值。
簡單實作 ASP.NET 提供查詢字串方法的完整支援,包括使用 HttpRequest 物件的 Params 屬性讀取查詢字串的方法。
使用查詢字串的缺點包括:
潛在安全性風險 使用者可透過瀏覽器使用者介面直接看到查詢字串中的資訊。使用者可以將 URL 標記為書籤或是將 URL 傳送給其他使用者,使得查詢字串中的資訊一起傳送。如果您顧慮查詢字串中的任何敏感資料,請考慮使用 POST 格式的隱藏欄位,而不是使用查詢字串。如需詳細資訊,請參閱 ASP.NET Web 應用程式安全性和 Web 應用程式的基本安全性實行方式。
容量限制 某些瀏覽器和用戶端裝置對於 URL 的長度都有 2083 個字元的限制。
用戶端方法狀態管理摘要
下表列出 ASP.NET 可用的用戶端狀態管理選項,並且提供何時使用每個選項的建議。
狀態管理選項 |
建議的使用方式 |
---|---|
檢視狀態 |
當您需要儲存網頁將回傳本身的少量資訊時使用。使用 ViewState 屬性會提供基本安全性功能。 |
控制項狀態 |
當您需要儲存伺服器來回往返之間控制的少量狀態資訊時使用。 |
隱藏欄位 |
您需要儲存網頁將回傳本身或其他網頁的少量資訊,而且不考量安全性的問題時使用。
注意事項:
您只能在送至伺服器的網頁上使用隱藏欄位。
|
Cookie |
當您需要在用戶端上儲存少量資訊,而且不考量安全性的問題時使用。 |
查詢字串 |
當您要將少量資訊從一網頁傳輸至另一網頁,而且不考量安全性的問題時使用。
注意事項:
只有在要求相同網頁,或透過連結要求另一網頁時,才能使用查詢字串。
|
伺服器端狀態管理選項
儲存網頁資訊的伺服器端選項,安全性通常比用戶端選項來得高,但是由於它們可能使用較多的 Web 伺服器資源,因此當資訊儲存較大時,延展性 (Scalability) 就會成為問題。ASP.NET 提供了一些實作伺服器端狀態管理的選項。如需詳細資訊,請參閱 ASP.NET 狀態管理概觀。
下列是 ASP.NET 支援的伺服器端狀態管理選項:
應用程式狀態
工作階段狀態
設定檔屬性
資料庫支援
應用程式狀態
ASP.NET 透過 HttpApplicationState 類別提供應用程式狀態,當做儲存整個應用程式全域變數特定資訊 (整個應用程式都可以看到) 的方法。應用程式狀態變數實際上就是 ASP.NET 應用程式的全域變數。如需詳細資訊,請參閱 ASP.NET 應用程式狀態概觀。
您可以在應用程式狀態中儲存應用程式專屬的值,然後就可以由伺服器管理它們。如需詳細資訊,請參閱 ASP.NET 狀態管理概觀。
讓多重工作階段共用並且不常變更的資料,是存入應用程式狀態變數的理想資料類型。
使用應用程式狀態的優點包括:
實作簡單 應用程式狀態容易使用、為 ASP 開發人員所熟悉,而且與其他 .NET Framework 類別一致。
應用程式範圍 因為應用程式中的所有頁面都可以存取應用程式狀態,所以將資訊儲存在應用程式狀態中,意味著只需要保存資訊的單一複本 (例如,相對於在工作階段狀態或個別網頁中保存許多資訊複本)。
使用應用程式狀態的缺點包括:
應用程式範圍 應用程式狀態的範圍也會是個缺點。儲存在應用程式狀態中的變數,只對應用程式在其中執行的特定處理序是全域變數,而且每個應用程式處理序都可能有不同的值。因此,您不能依賴應用程式狀態儲存唯一值或更新 Web-Garden 和 Web-Farm 組態中的全域計數器。
有限的資料耐久性 因為儲存在應用程式狀態中的全域資料是動態的,所以如果伺服器毀損、升級或關機而終結包含它的 Web 伺服器處理序,這些資料將會遺失。
資源需求 應用程式狀態需要伺服器記憶體,這可能影響伺服器的效能以及應用程式的延展性 (Scalability)。
小心設計和實作應用程式狀態可以增進 Web 應用程式的效能。例如,將常用且相對靜態的資料集置於應用程式狀態中,可以降低對資料庫要求資料的整體數目,進而增進網站的效能。但是,在效能上也有需要取捨的地方。含有大型資訊區塊的應用程式狀態變數,會在伺服器負荷增加時降低 Web 伺服器的效能。由儲存在應用程式狀態中之變數所佔用的記憶體,會一直到值被移除或者取代時才會被釋放。因此,使用應用程式狀態變數時,最好配合使用小型、不常變更的資料集。如需詳細資訊,請參閱效能概觀。
工作階段狀態
ASP.NET 提供可經由 HttpSessionState 類別取得的工作階段狀態,當做儲存工作階段特定資訊的方法,而這些資訊只能在工作階段內檢視。ASP.NET 工作階段狀態會在限制時間間隔內,將來自相同瀏覽器的要求識別為一個工作階段,並且提供保存這個工作階段期間內之變數值的功能。如需詳細資訊,請參閱 ASP.NET 狀態管理概觀和 ASP.NET 工作階段狀態概觀。
您可以將工作階段專屬的值和物件儲存在工作階段狀態中,然後它們就可以由伺服器管理,並且可供瀏覽器或用戶端裝置使用。最適合儲存在工作階段狀態變數中的資料,就是由某個個別的工作階段專用、存留期短暫且敏感的資料。
使用工作階段狀態的優點包括:
實作簡單 應用程式狀態容易使用、為 ASP 開發人員所熟悉,而且與其他 .NET Framework 類別一致。
工作階段特定事件 應用程式可以引發和使用工作階段管理事件。
資料保存性 因為放置在工作階段狀態變數中的資料是儲存於其他處理序空間中,因此不會因為網際網路資訊服務 (IIS) 和背景工作處理序重新啟動而遺失工作階段資料。此外,工作階段資料可以橫跨 Web 伺服陣列或 Web 處理序區中的多個處理序而保留下來。
平台延展性 工作階段狀態可用於多電腦和多處理序組態中,因此可最佳化延展性的案例。
Cookieless 支援 雖然工作階段狀態常與 Cookie 搭配使用,以提供 Web 應用程式使用者識別功能,但是工作階段狀態仍可用於不支援 HTTP Cookie 的瀏覽器。但是,在 Cookieless 的情況下使用工作階段狀態,需要將工作階段識別項置於查詢字串中,就會受到本主題在查詢字串章節中描述的安全性問題所影響。如需在 Cookieless 的情況下使用工作階段狀態的詳細資訊,請參閱 管理 ASP.NET 網站。
擴充性 您可以撰寫自己的工作階段狀態提供者,自訂和擴充工作階段狀態。然後工作階段狀態資料可以使用自訂資料格式,儲存在各種資料儲存機制中,例如資料庫、XML 檔、或甚至是 Web 服務。如需詳細資訊,請參閱實作工作階段狀態存放區提供者。
使用工作階段狀態的缺點包括:
- 效能考量 工作階段變數在移除或取代之前都會處於記憶體中,因此可能會降低伺服器效能。含有資訊區塊 (如,大型資料集) 的工作階段狀態變數,在伺服器負荷增加時可能會影響 Web 伺服器的效能。
設定檔屬性
ASP.NET 提供稱為設定檔屬性的功能,可以讓您儲存使用者相關的資料。這項功能類似工作階段狀態,除了當使用者工作階段過期時設定檔的資料不會遺失之外。設定檔屬性功能會使用 ASP.NET 設定檔,其使用永續性格式儲存並且與個別使用者相關聯。ASP.NET 設定檔可讓您輕易地管理使用者資訊,而不需要建立和維護您的資料庫。此外,設定檔使用強型別 (Strongly Typed) API 將使用者資訊成為可用,您可以在應用程式中的任何地方存取這些 API。您可以在設定檔中儲存任何型別的物件。ASP.NET 設定檔功能提供泛型的儲存系統,讓您定義和維護幾乎任何種類的資料,但是資料仍然可以用型別安全的方式使用。如需詳細資訊,請參閱 ASP.NET 設定檔屬性概觀。
使用設定檔屬性的優點包括:
資料保存性 因為放置在設定檔屬性中的資料是儲存在外部機制中,因此不會因為 IIS 和背景工作處理序重新啟動而遺失資料。此外,設定檔屬性可以橫跨 Web 伺服陣列或 Web 處理序區中的多個處理序而保留下來。
平台延展性 設定檔屬性可用於多電腦和多處理序組態中,因此可最佳化延展性的案例。
擴充性 為了使用設定檔屬性,您必須設定設定檔提供者。ASP.NET 包含一個 SqlProfileProvider 類別,可讓您將設定檔資料儲存在 SQL 資料庫中,但是您也可以建立自己的設定檔提供者類別,將設定檔資料以自訂格式儲存 (如 XML 檔案),以及儲存至自訂儲存機制 (如 Web 服務)。如需詳細資訊,請參閱 ASP.NET 設定檔提供者和實作設定檔提供者。
使用設定檔屬性的缺點包括:
效能考量 設定檔屬性的效能通常都比使用工作階段狀態慢,因為資料是保存在資料存放區而不是記憶體中。
額外設定的需求 設定檔屬性功能不像工作階段狀態,需要進行大量設定才能使用。若要使用設定檔屬性,除了設定設定檔提供者以外,也必須預先設定希望儲存的所有設定檔屬性。如需詳細資訊,請參閱 ASP.NET 設定檔屬性概觀和定義 ASP.NET 設定檔屬性。
資料維護 設定檔屬性需要進行一些維護工作。因為設定檔資料保存在靜態的儲存區中,所以您必須確定在資料變成過時的時候,應用程式會呼叫設定檔提供者所提供的適當清除機制。
資料庫支援
在某些情況下,您可能想要使用資料庫支援維護網站上的狀態。資料庫支援通常是配合 Cookie 或工作階段狀態一同使用。例如,電子商務網站常會因為下列原因,使用關聯式資料庫來維護狀態資訊:
安全性
個人化
一致性
資料採擷
以下是支援 Cookie 的資料庫網站通常會具備的功能:
安全性 訪客在站台登入網頁中輸入帳戶名稱和密碼。站台基礎結構會利用登入值查詢資料庫,判斷使用者是否具有使用您網站的權限。如果資料庫驗證了這位使用者的資訊,網站就會散發一個含有唯一 ID 的有效 Cookie,給該用戶端電腦上的這位使用者,也會授與這位使用者存取權限。
個人化 適當使用安全性資訊,您的站台可以藉由讀取用戶端電腦上的 Cookie 來區別每個使用者。網站在資料庫中通常會有描述某位使用者 (由唯一的 ID 所識別) 的喜好設定。這種關聯性 (Relationship) 就是所謂的個人化。網站可以透過使用包含在 Cookie 中的唯一 ID,找出使用者的偏好,並且將與使用者特定要求有關,而且隨著時間反應使用者偏好的內容和資訊呈現在使用者面前。
一致性 如果您已經建立商務網站,您可能想要保留購買您網站上產品和服務的交易記錄。您可以安心地將這項資訊儲存在資料庫中,並利用使用者的唯一 ID 來參考。它可用來判斷購買交易是否完成,也可判斷當購買交易失敗時要採取的措施。這項資訊也可用來將透過您網站所下訂單的狀態告知使用者。
資料採擷 您可安心地將網站的使用、訪客、或產品交易的資訊儲存在資料庫中。例如,您的業務開發部門可能希望使用從網站收集的資料,用以判斷明年的產品線或經銷通路策略。您的行銷部門可能希望檢視站台使用者的統計資訊。您的工程和技術支援部門可能希望檢視交易,並記下購買處理序可改善之處。多數企業層級的關聯式資料庫 (例如 Microsoft SQL Server) 都包含功能完善的工具集,以供多數資料採擷專案之用。
在上述案例中,只要將網站設計成在每個一般性階段中,藉由使用唯一的 ID 反複查詢資料庫,就可以維護網站的狀態。採用這種方式,使用者將會感受到這個網站不僅記得他們,而且還會個別地回應他們。
使用資料庫維護狀態的優點包括:
安全性 存取資料庫需要嚴密的驗證和授權。
儲存空間 您可以在資料庫中儲存大量資訊。
資料保存性 資料庫資訊儲存的時間沒有限制,不受限於 Web 伺服器的可用性。
強固性和資料完整性 資料庫包含許多維護良好資料的功能,包括觸發程序 (Trigger) 和參考完整性 (Referential Integrity)、交易等。只要將有關交易的資訊保存在資料庫中 (而不是保存在工作階段狀態中),您就可以很輕易地從錯誤中還原。
協助工具 儲存在資料庫中的資料可由各種不同的資訊處理工具存取。
廣泛支援 可使用各種資料庫工具和許多自訂組態。
使用資料庫維護狀態的缺點包括:
複雜度 使用資料庫支援狀態管理,需要更複雜的硬體和軟體組態。
效能考量 不良的關聯式資料模型建構會造成延展性的問題。同時,對資料庫使用太多查詢可能會影響伺服器的效能。
伺服器端方法狀態管理摘要
下表列出 ASP.NET 可用的伺服器端狀態管理選項,並且提供何時使用每個選項的建議。
狀態管理選項 |
建議的使用方式 |
---|---|
應用程式狀態 |
當您正在儲存變更頻率低、由許多使用者使用的全域資訊、而且不考量安全性的問題時使用。請勿在應用程式狀態中儲存大量資訊。 |
工作階段狀態 |
當您要儲存個別工作階段專用且存留期短暫的資訊,同時必須顧慮安全性時使用。請勿在工作階段狀態中儲存大量資訊。請注意,工作階段狀態物件會在您應用程式中每個工作階段的存留期期間建立並維護。在擁有許多使用者的應用程式中,這可能會佔用大量的伺服器資源並且影響延展性。 |
設定檔屬性 |
當您儲存在工作階段過期後需要保存的使用者特定資訊,並且在後續造訪應用程式需要再度擷取時使用。 |
資料庫支援 |
當您儲存大量資訊、管理交易、或是資料必須不受應用程式和工作階段重新啟動的影響時使用。資料採擷是重要的,而且也必須顧慮安全性。 |