asp.net web Form 網頁是基於HTTP的,它們沒有狀態, 這意味著它們不知道所有的請求是否來自
同一台用戶端電腦,網頁是受到了破壞,以及是否得到了重新整理,這樣就可能造成資訊的
丟失。 於是, 狀態管理就成了開發網路應用程式的一個實實在在的問題。
在ASP中能夠通過Cookie 、查詢字串、 應用程式、會話(Session) 等輕易解決這些問題。
現在在ASP.NET環境中,我們依然可以使用這些功能,並且功能更加強大。
狀態管理分為服務端和用戶端兩種情況, 這裡只是介紹 服務端狀態管理:
與Application對象不同的是, ASP.NET 的Session對象可以在IIS伺服器或者背景工作處理序重新啟動時
恢複啟動前的狀態而不丟失其中的資料。這是因為儲存在Session中的所以資訊都預設的儲存在
一個作為Windows服務啟動並執行狀態伺服器處理序中。狀態可以被序列化並以二進位形式儲存在記憶體中。
程式員可以懸著使用Microsoft Sql server資料庫來儲存資料。
狀態伺服器服務和狀態資訊可以和web應用程式一起存在於同一台伺服器上,也可以儲存到外部的
狀態伺服器上。 為了指定如何儲存資訊,程式員可以在web.config檔案中編寫適當的配置。
ASP.NET工作階段狀態模組在Web.config檔案中<System.web>標記下的<Sessionstate>標記的mode屬性來決定
該屬性的四種可能的值: Off、 Inproc StateServer 和SQLserver。
1 Inproc是預設的設定
它允許“無Cookie”的會話,以及在伺服器之外儲存
會話資料。ASP.NET工作階段狀態模組在Web.config檔案中像下面這樣配置:
<sessionState mode="InProc" cookieless="false" timeout="20" />
在這個例子中,mode屬性設為InProc(預設值),表明工作階段狀態要由ASP.NET儲存到記憶體中,而且
不用Cookie來傳遞會話ID。相反,會話ID要直接插入一個網頁URL的查詢字串中。例如,採用
InProc模式並建立一個會話之後,調用一個假想的ASP.NET網頁時,需要採用下面這樣的URL:
http://my.website.com/(12mfju55vgblubjlwsi4dgjq)/education.aspx
圓括弧中長長的字母、數字字串就是會話ID。ASP.NET引擎從查詢字元中提取會話ID,並將使用者
請求與特定會話聯絡起來。採取這種方式,不管Cookie還是隱藏表單欄位都用不著了。
所以,即使網頁中沒有使用表單,也能加入會話。
但是這種方法,應用程式的狀態將依賴於 ASP.NET進程, 當IIS進程崩潰或者正常重啟時,儲存在
進程中的狀態將丟失。
2 mode屬性設為Off
和從前的ASP一樣,ASP.NET的工作階段狀態管理是要產生開銷的。所以,假如某個網頁不需要訪問
Session對象,開發人員應將那個頁的Page先行編譯指令的EnableSessionState屬性設為False。
要為整個網站禁用工作階段狀態,可在Web.config檔案中將sessionState元素的mode屬性設為Off。
為了克服inproc 模式的缺點, ASP.NET 提供了兩種進程外儲存工作階段狀態的方法。
3 StateServer會話管理
將mode屬性設為StateServer,也就是將會話資料存放區到單獨的記憶體緩衝區中,再由單獨一台機器上運行
的Windows服務來控制這個緩衝區。狀態服務全稱是“ASP.NET State Service ”(aspnet_state.exe),
它由Web.config檔案中的stateConnectionString屬性來配置。該屬性指定了服務所在的伺服器,以及要監
視的連接埠:
<sessionState mode="StateServer"
stateConnectionString="tcpip=myserver:42424"
cookieless="false" timeout="20" />
在這個例子中,狀態服務在一台名為myserver的機器的42424連接埠(預設連接埠)運行。要在伺服器上改變
連接埠,可編輯HKLM\SYSTEM\CurrentControlSet\Services\aspnet_state登錄機碼中的Port值。
顯然,使用狀態服務的優點在於進程隔離,並可在Web farm中共用。 使用這種模式,工作階段狀態的儲存將不
依賴於iis進程的失敗或者重啟,然而,一旦狀態服務中止,所有會話資料都會丟失。換言之,狀態服務不
像SQL Server那樣能持久儲存資料;它只是將資料存放區在記憶體中。
4 用SQL Server進行會話管理
ASP.NET還允許將會話資料存放區到一個資料庫伺服器中,方法是將mode屬性變成SqlServer。
在這種情況下,ASP.NET嘗試將會話資料存放區到由sqlConnectionString屬性(其中包含資料來源以及登入服
務器所需的安全憑證)指定的SQL Server中。
為了用恰當的資料庫物件來配置SQL erver,管理員還需要建立ASPState資料庫,
方法是運行WinDir\Microsoft.Net\Framework\Version檔案夾中的InstallState.sql指令碼(WinDir是服務
器的Windows檔案夾,而Version是你使用的.NET架構版本的安裝資料夾)。
要配置SQL伺服器,可以在命令列中運行SQL Server 提供的命令列工具osql.exe
osql -S [ server name] -U [user] -P [password] <InstallSqlState.sql
例如
osql -S (local)\NetSDK -U sa -P "" -i InstallSqlState.sql
在這裡使用者名稱必須是SQL伺服器上的sa帳號,或者具有同等許可權的其他帳號。有興趣的讀者可以開啟
這個指令檔來瞭解ASP.NET是如何和SQL Server配合實現狀態管理的。
卸載這些表和預存程序,可以使用UninstallSqlState.sql指令碼,使用方法與上面類似。
做好必要的資料庫準備工作後,將web.config 檔案中的sessionstate 元素的mode改為"sqlserver"
,並且指定SQL連接字串。具體如下:
mode="sqlserver"
sqlConnectionString="data source=127.0.0.1; userid=sa; password="
配置好SQL Server後,應用程式代碼運行時就和InProc模式沒有什麼區別。但要注意的是,由於資料不存
儲在本地記憶體,所以儲存工作階段狀態的對象需要進行序列化和還原序列化,以便通過網路傳給資料庫伺服器,
以及從資料庫伺服器傳回。這當然會影響效能。通過在資料庫中儲存工作階段狀態,可分別針對擴充性及可靠
性來有效地平衡效能。另外,可以利用SQL Server的叢集,使狀態儲存不依賴於單個的SQL Server, 這樣就可以為應用程式提供極大限度的可靠性。