在壇子裡經常看到一些關於Session的問題,下面做一個總結,希望對大家有所幫助:
問:為什麼Session在有些機器上偶爾會丟失?
答:可能和機器的環境有關系,比如:防火牆或者殺毒軟件等,嘗試關閉防火牆。
問:為什麼當調用Session.Abandon時並沒有激發Session_End方法?
答:首先Session_End方法只支持InProc(進程內的)類型的Session。其次要激發Session_End方法,必須存在Session(即系統中已經使用Session了),並且至少要完成一次請求(在這次請求中會調用該方法)。
問:為什麼當我在InProc模式下使用Session會經常丟失?
答:該問題通常是由於應用程序被回收導致的,因為當使用進程內Session時,Session是保存在aspnet_wp進程中,當該進程被回收Session自然也就沒有了,確定該進程是否被回收可以通過查看系統的事件查看器獲得信息。
具體信息請參考:
Session variables are lost intermittently in ASP.NET applications
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q316148
在1.0的時候也有一個bug會導致工作進程被回收並重啟,該bug已經在1.1和sp2中修復。
關於該bug的詳細信息請參考:
ASP.NET Worker Process (Aspnet_wp.exe) Is Recycled Unexpectedly.
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q321792
問:為什麼當Session超時或者Abandoned後,新Session的ID和原來的相同?
答:因為SessionID是保存在客戶端浏覽器的實例裡,當Session超時在服務器重新建立Session時,將使用浏覽器傳來的SessionID,所以當Session超時後,再重新建立後SessionID並不變。
問:為什麼每次請求的SessionID都不相同?
答:該問題可能是沒有在Session裡面保存任何信息引起的,即程序中任何地方都沒有使用Session。當Session中保存信息之後SessionID將一直和浏覽器相關,此時的SessionID將不會在變化。
問:ASP和ASP.NET之間是否可以共享Session?
答:可以。但是這是一個比較復雜的過程,微軟提供了官方的解決方案,請參考:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/ConvertToASPNET.asp
問:什麼類型的對象可以保存在Session裡?
答:這依賴使用的Session的模式,當使用的是進程內(InProc)的Session那麼可以輕松的保存任何對象。如果你使用了非InProc的模式,則只能保存可以序列化和反序列化的對象,如果此時保存的對象不支持序列化,則不能保存到這種模式(非InProc)的Session裡。
問:為什麼在Session_End中不能使用Response.Redirect和Server.Transfer方法跳轉頁面?
答:Session_End是一個在服務器內部激發的事件處理函數。它是基於一個服務器內部的計時器的,在激發該事件時服務器上並沒有相關的HttpRequest對象,因此此時並不能使用Response.Redirect和Server.Transfer方法。
問:在Session_End中是否可以獲得HttpContext對象?
答:不行,因為這個事件並沒有和任何的請求(Request)相關聯,沒有基於請求的上下文。
問:在Web Service中該如何使用Session?
答:為了在Web Service中使用Session,需要在Web Service的調用方做一些額外的工作,必須保存和存儲調用Web Service時使用的Cookie。詳細信息請參考MSDN文檔的HttpWebClientProtocol.CookieContainer屬性。然而,如果你使用代理服務器訪問Web Service由於框架的限制,兩者不能共享Session。
問:在自定義自己的HttpHandler的時候,為什麼不能使用Session?
答:在實現自己的HttpHandler的時候,如果希望使用Session必須實現下面的兩個標記接口中的一個:IRequiresSessionState和IReadOnlySessionState,這些接口沒有任何方法需要實現,只是一個標記接口和使用INamingContainer接口的方法一樣。
問:當我使用webfarm時,當我重定向到其他的Web服務器時Session為什麼會丟失?
答:詳細信息請參考:
PRB: Session State Is Lost in Web Farm If You Use SqlServer or StateServer Session Mode
http://support.microsoft.com/default.aspx?scid=kb;en-us;325056
問:為什麼我的Session在Application_OnAcquireRequestState方法中無效?
答:Session只有在HttpApplication.AcquireRequestState事件調用以後才會有效。
詳細信息請參考:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconhandlingpublicevents.asp
問:如果使用了cookieless,我該如何從HTTP頁面定向到HTTPS?
答:請嘗試下面的方法:
String originalUrl = "/fxtest3/sub/foo2.aspx";
String modifiedUrl = "https://localhost" + Response.ApplyAppPathModifier(originalUrl);
Response.Redirect(modifiedUrl);
問:Session在global.asax中的那些事件中有效?
答:Session只有在AcquireRequestState事件之後有效,該事件之後的事件都可以使用Session。
問:如何獲得當前Session中保存的所有對象?
答:可以通過遍歷所有的Session.Keys來獲得。代碼如下:
ArrayList sessionCollection = new ArrayList();
foreach (string strKey in Session.Keys){
sessionCollection.Add(Session[strKey]);
}
問:是否可以在不同的應用程序中共享Session?
答:不能直接共享。可以參考如何在ASP和ASP.NET之間共享Session。
問:Session.Abandon和Session.Clear有何不同?
答:主要的不同之處在於當使用Session.Abandon時,會調用Session_End方法(InProc模式下)。當下一個請求到來時將激發Session_Start方法。而Session.Clear只是清除Session中的所有數據並不會中止該Session,因此也不會調用那些方法。
問:為了可以順序訪問Session的狀態值,Session是否提供了鎖定機制?
答:Session實現了Reader/Writer的鎖機制:
當頁面對Session具有可寫功能(即頁面有<%@ Page EnableSessionState="True" %>標記),此時直到請求完成該頁面的Session持有一個寫鎖定。