【考點】
ASP.NET中Session的多種儲存方法。
【出現頻率】
★★★☆☆
【解答】
使用進程內工作階段狀態模
式時,如果aspnet_wp.exe或應用程式定義域重新啟動,則工作階段狀態資料將丟失。可以用Sate server或SQL Server資料庫的方式存
儲Session的成對的名稱和數值集合,不過這些方式效率稍低,並且無法捕獲Session的END事件。
【分析】
本題主要考查面試者是否能解決Session丟值問題,因為aspnet_wp.exe進程或應用程式定義域重新啟動時,會導致Session資料的丟失。引發這種情況的原因可能為:
修改了Global.asax檔案。
修改了Web.config檔案。
更改WEB應用程式的bin目錄路徑。
殺毒軟體掃描(可能發生修改)了Global.asax 檔案、Web.config檔案或Web應用程式的Bin目錄下的檔案。
在Web.config設定檔的<processModel>元素中,可設定導致新進程在條件被滿足時啟動的屬性,不過這並不屬於BUG。
在ASP.NET的應用程式中,Web.config設定檔中關於Session的一般設定如下:
<sessionState mode='InProc'
stateConnectionString='tcpip=127.0.0.1:42424'
sqlConnectionString='data source=127.0.0.1;Trusted_Connection=yes' cookieless='true' timeout='60' />
以
上代碼中的<sessionState />節點中有個“mode”屬性,其取值可以為“InProc”、“StateServer”和
“SQLServer”,預設值為“InProc”。預設值就是將Session儲存在進程內(IIS5是aspnet_wp.exe,而IIS6是
W3wp.exe),在系統發生某些意外事件時該進程可能會重啟,所以造成了儲存在該進程內的Session丟失。相對而言,如果“mode”屬性取值為
“StateServer”或“SQLServer”,即可避免進程重啟後丟失Session值的情況,因為這兩種方法儲存Session值是進程外的。
首
先將“mode”屬性修改為“StateServer”。StateServer是原生一個網路服務,在服務管理員中可以看到這個名為
“ASP.NET State Service”的服務,預設情況是不啟動的。如果要使用StateServer方式儲存Session值,當
“mode”屬性修改為“StateServer”之後,編程者需要啟動“ASP.NET State Service”的服務。在單擊
Windows XP作業系統的“開始”菜單,選擇“運行”命令,輸入“services.msc”,然後單擊“確定”按鈕即可開啟服務管理員,找到
11.3所示的網路服務,並啟動該服務。圖11.3 啟動ASP.NET State Service服務
除了使用圖形化介面啟動該服務,還可以在命令列中輸入以下代碼所示的命令,以啟動該服務。
net start aspnet_state
現
在,編程者即可利用原生StateServer方式來儲存Session值了,除非伺服器重啟或者“ASP.NET State Service”服務
停止,否則Session值可以在逾時時間內穩定地存在。編程者還可以將Session值通過其他電腦的“ASP.NET State Service”
服務來儲存,只需要在<sessionState />元素中修改“stateConnectionString”的屬性,將IP地址修改為
其他的電腦,並在其他電腦上啟動“ASP.NET State Service”服務即可。通過這種操作,編程者就可以使位於不同伺服器上的
ASP.NET應用程式共用Session值。
如果WEB應用程式要求Session值具有更好的持久性和可靠性,即使伺服器重啟後
Session值仍然不丟失,可以將“mode”屬性修改為“SQLServer”。不僅如此,還需要修改sqlConnectionString屬性,
以確保正確地串連SQLServer資料庫。微軟提供了SQL指令檔以建立儲存Session值的資料庫,該資料庫名為ASPState,包含了大量被
ASP.NET運行庫調用的資源(如預存程序等)。把Session值儲存於資料庫中雖然可靠,但速度較慢。
說明:使用非進程內方法儲存Session值應確保HttpSessionState對象內的自訂類型是可序列化的,即類型被標記了[Serializable]特性。