asp.net Session的實現:
asp.net的Session是基於HttpModule技術做的,HttpModule可以在請求被處理之前,對請求進行狀態控制,由於Session本身就是用來做狀態維護的,因此用HttpModule做Session是再合適不過了。
ASP.NET中Session的狀態保持方式
ASP.NET提供了Session對象,從而允許程式員識別、儲存和處理同一個瀏覽器對象對伺服器上某個特定網路應用程式的若干次請求的上下文資訊。Session對應瀏覽器與伺服器的同一次對話,在瀏覽器第一請求網路應用程式的某個頁面時,伺服器會觸發Session_onStart事件;在對話逾時或者被關閉的時候會觸發Session_onEnd 事件。程式員可以在代碼中響應這兩個事件來處理與同一次對話相關的任務,如開闢和釋放該次對話要使用的資源等。
在ASP.NET的程式中要使用Session對象時,必須確保頁面的@page指令中EnableSessionState屬性是True或者Readonly,並且在web.config檔案中正確的設定了SessionState屬性。
ASP.NET中Session的狀態保持是由web.config檔案中的<system.web>標記下的<sessionstate>標記的mode屬性來決定的。該屬性有四種可能的值:Off、Inproc、StateServer和SQlServer.設為Off會禁用Session.
Inproc是預設的設定,這種模式和以前的ASP的工作階段狀態的方法是類似的,會話的狀態會被儲存在ASP.NET進程中,它的優點是顯而易見的:效能。進程內的資料訪問自然會比誇進程的訪問快。然而,這種方法Session的狀態依賴於ASP.NET進程,當IIS進程崩潰或者正常重起啟時,儲存在進程中的狀態將丟失。
為了克服Inproc模式的缺點,ASP.NET提供了兩種進程外保持工作階段狀態的方法。ASP.NET首先提供了提供了一個Windows服務:ASPState,這個服務啟動後,ASP.NET應用程式可以將mode屬性設定為“SateServer”,來使用這個Windows服務提供的狀態管理方法。
除了在web.config檔案中設定mode屬性為StateServer外,還必須設定運行StateServer伺服器的IP地址和連接埠號碼.如果在IIS所在的機器運行StateServer則IP地址就是127.0.0.1,連接埠號碼通常是42424.配置如下:
mode=”StateServer”
stateConnectionString="tcpip=127.0.0.1:42424"
使用這種模式,工作階段狀態的儲存將不依賴IIS進程的失敗或者重啟,會話的狀態將儲存在StateServer進程的記憶體空間中。
另一種工作階段狀態模式是SQLServer模式。這種模式是將會話的狀態儲存在SQL Server資料庫中的。使用這種模式前,必須至少有一台SQL Server伺服器,並在伺服器中建立需要的表和預存程序。.NET SDK提供了兩個指令碼來簡化這個工作:InstallSqlState.sql和UnInstallSqlState.sql。這兩國檔案存放在下面路徑中:
<%SYSTEMDRIVER%>\Winnt\Microsoft.NET\Framework\<%version%>\
要配置SQL Server 服務器,可以在命令列中運行SQL Server提供的命令列工具osql.exe
osql -s [server name] -u [user] -p [password] <InstallSqlState.sql
例如:osql -s (local) -u as -p “”-i InstallSqlState.sql
做好必要的資料庫準備工作後,將web.config檔案中的sessionstate元素的mode屬性改為”sqlserver”,並指定SQL連接字串。具體如下:
mode="SQLServer"
sqlConnectionString="data source=127.0.0.1;userid=sa;password=;Trusted_Connection=yes"
使用SQLServer模式處了可以使Session的狀態不依賴於IIS伺服器之外,還可以利用SQL Server的叢集,使狀態儲存不依賴於單個的SQL Server,這樣就可以為應用程式提供極大的可靠性。
丟失原因:
轉(1):Asp.net 預設配置下,Session莫名丟失的原因及解決辦法
正常操作情況下Session會無故丟失。因為程式是在不停的被操作,排除Session逾時的可能。另外,Session逾時時間被設定成60分鐘,不會這麼快就逾時的。
這次到CSDN上搜了一下文章,發現好多人在討論這個問題,然後我又google了一下,發現微軟網站上也有類似的內容。
現在我就把原因和解決辦法寫出來。原因:由於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,它可以有3種取值:InProc、StateServer?SQLServer(大小寫敏感)。預設情況下是InProc,也就是將Session儲存在進程內(IIS5是aspnet_wp.exe,而IIS6是W3wp.exe),這個進程不穩定,在某些事件發生時,進程會重起,所以造成了儲存在該進程內的Session丟失。[asp的Session是具有進程依賴性的。ASP Session狀態存於IIS的進程中,也就是inetinfo.exe這個程式。所以當inetinfo.exe進程崩潰時,這些資訊也就丟失。]
哪些情況下該進程會重起呢?微軟的一篇文章告訴了我們:
1、設定檔中processModel標籤的memoryLimit屬性
2、Global.asax或者Web.config檔案被更改
3、Bin檔案夾中的Web程式(DLL)被修改
4、殺毒軟體掃描了一些.config檔案。
更多的資訊請參考PRB: Session variables are lost intermittently in ASP.NET applications(連結:http://support.microsoft.com/kb/316148/EN-US/)
解決辦法:
前面說到的sessionState標籤中mode屬性可以有三個取值,除了InProc之外,還可以為StateServer、SQLServer。這兩種存Session的方法都是進程外的,所以當aspnet_wp.exe重起的時候,不會影響到Session。
現在請將mode設定為StateServer。StateServer是原生一個服務,可以在系統服務裡看到服務名為ASP.NET State Service的服務,預設情況是不啟動的。當我們設定mode為StateServer之後,請手工將該服務啟動。這樣,我們就能利用原生StateService來儲存Session了,除非電腦重啟或者StateService崩掉,否則Session是不會丟的(因Session逾時被丟棄是正常的)。
除此之外,我們還可以將Session通過其他電腦的StateService來儲存[如使用狀態伺服器]。具體的修改是這樣的。同樣還在sessionState標籤中,有個stateConnectionString='tcpip=127.0.0.1:42424'屬性,其中有個ip地址,預設為本機(127.0.0.1),你可以將其改成你所知的運行了StateService服務的電腦IP,這樣就可以實現位於不同電腦上的Asp.net程式互連Session了。
如果你有更高的要求,需要在服務期重啟時Session也不丟失,可以考慮將mode設定成SQLServer,同樣需要修改sqlConnectionString屬性。關於使用SQLServer儲存Session的操作,請訪問這裡。
在使用StateServer或者SQLServer儲存Session時,所有需要儲存到Session的對象除了基礎資料型別 (Elementary Data Type)(預設的資料類型,如int、string等)外,都必須序列化。只需將[Serializable]標籤放到要序列化的類前就可以了。
如:
[Serializable]
public class MyClass
{
......
}
具體的序列化相關的知識請參這裡(http://www.microsoft.com/china/msdn/archives/library/dndotnet/html/objserializ.asp#objserializ_topic4)。
至此,問題解決。
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/aMao_14189/archive/2008/10/29/3174006.aspx