【考點】
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]特性。
轉:http://blog.163.com/yds666666@126/blog/static/372897692009630104445136/