ASP.NET 工作階段狀態

來源:互聯網
上載者:User

1、ASP.NET 工作階段狀態
2、工作階段狀態模式
3、ASP.NET在不同應用程式之間共用Session
4、Session無故丟失
5、用戶端使用Cookieless的方式儲存Session資訊
6、Session.SessionID 固定

1、ASP.NET 工作階段狀態

      工作階段狀態可在以下情況下使用:儲存特定於單獨會話的短期資訊,並且需要較高的安全性。不要在工作階段狀態中儲存大量的資訊。需要注意,將為應用程式中每一會話的生存期建立並維護工作階段狀態對象。在支援許多使用者的應用程式中,這可能會佔用大量伺服器資源並影響可縮放性。*p1

      ASP.NET 預設情況下將會話資訊儲存在 ASP.NET 應用程式的記憶體空間。您可以使用一個獨立的服務儲存會話資訊以便重新啟動 ASP.NET 應用程式後會話資訊仍然保留;或將會話資訊儲存在 SQL Server 中以便會話資訊可供網路場中的多個 Web 服務器使用(重新啟動 ASP.NET 應用程式後會話資訊也會保留);或將會話資訊儲存在自訂資料存放區區。有關更多資訊,請參見工作階段狀態模式。

      除了工作階段狀態外,ASP.NET 還提供在應用程式中保留資料的一些其他方式。有關每種方式的比較,請參見 ASP.NET 狀態管理建議。*p2

注:
*p1:ASP.NET 狀態管理建議 http://msdn.microsoft.com/zh-cn/library/z1hkazw7(v=VS.80).aspx
*p2:ASP.NET 工作階段狀態 http://msdn.microsoft.com/zh-cn/library/87069683(v=VS.80).aspx


2、工作階段狀態模式

      ASP.NET 工作階段狀態支援若干用於會話資料的儲存選項。每個選項都由 SessionStateMode 枚舉中的一個值標識。下面的列表描述了可用的工作階段狀態模式:

 

  • InProc 模式,此模式將工作階段狀態儲存在 Web 服務器上的記憶體中。這是預設設定。注意:它是唯一支援 Session_OnEnd 事件的模式。

  • StateServer 模式,此模式將工作階段狀態儲存在一個名為 ASP.NET 狀態服務的單獨進程中。這確保了在重新啟動 Web 應用程式時會保留工作階段狀態,並讓工作階段狀態可用於網路場中的多個 Web 服務器。注意:如果模式設定為 StateServer,則儲存在工作階段狀態中的對象必須是可序列化的。
  • SQLServer 模式,將工作階段狀態儲存到一個 SQL Server 資料庫中。這確保了在重新啟動 Web 應用程式時會保留工作階段狀態,並讓工作階段狀態可用於網路場中的多個 Web 服務器。注意:如果是 SQL Server 模式,則儲存在工作階段狀態中的對象必須是可序列化的。
  • Custom 模式,此模式允許您指定自訂儲存提供者。
  • Off 模式,此模式禁用工作階段狀態。

      通過在應用程式的 Web.config 檔案中為 sessionState 元素的 mode 屬性分配一個 SessionStateMode 枚舉值,可以指定要讓 ASP.NET 工作階段狀態使用的模式。除了 InProc 和 Off 之外,其他模式都需要附加參數,例如將在本主題後面討論的連接字串值。通過訪問 System.Web.SessionState.HttpSessionState.Mode 屬性的值,可以查看當前選定的工作階段狀態。*p3

註:
*p3:工作階段狀態模式 http://msdn.microsoft.com/zh-cn/library/ms178586(v=VS.80).aspx

3、ASP.NET在不同應用程式之間共用Session *p4

      多個單獨的應用程式,如何將這些模組集中身分識別驗證與授權過程

方案1:
將每個獨立的Web應用程式放到統一的解決方案中,實現起來複雜,易用性不高。

方案2:利用Session會話共用
InProc模式,Session被儲存在IIS進程中,每個虛擬目錄是隔離的,所以無法共用Session。

StateServer 模式,雖然是獨立的狀態伺服器(進程),但在記憶體中這些應用程式還是隔離的。

SQLServer 模式,由於對Session的全部操作都是由預存程序來實現的,而且預存程序未進行加密,可以通過修改預存程序的內部結構來達到共用的目的。

      ASPState資料庫ASPStateTempApplications表中儲存的是應用程式資訊,每個應用程式在啟動的時候在這裡會註冊一條記錄,包括應用程式的ID(通過雜湊演算法產生的)和應用程式名稱。有多少個應用程式,在這個表裡就對應多少條記錄。那我們現在要做的是把這些記錄變成一條記錄,也就是要欺騙Framework,讓它認為這些不同的應用程式是同一個應用程式。

      TempGetAppID預存程序,這個預存程序是用於通過傳遞應用程式名稱來得到應用程式ID資訊的。每個應用程式在調用這個過程時,這個過程會去AspStateTempApplications中檢查是否有相應的記錄,如果沒有,就插入記錄,然後返回相應的ID。

    ALTER PROCEDURE [dbo].[TempGetAppID]
    @appName    tAppName,
    @appId      int OUTPUT
    AS
    SET @appName = LOWER(@appName)
    --變數值固定,使所有應用程式通用為一個
    SET @appName = '/lm/w3svc/650056020/root/personnel/share'
    SET @appId = NULL

    SELECT @appId = AppId
    FROM [tempdb].dbo.ASPStateTempApplications
    WHERE AppName = @appName

註:
*p4:ASP.NET在不同應用程式之間共用Session  http://www.3qsoft.com/Article.aspx?ID=173


4、Session無故丟失 *p5

mode="InProc" 
== 
預設的配置方式很容易丟失Session 請參考 

asp中Session的工作原理: 
asp的Session是具有進程依賴性的。ASP Session狀態存於IIS的進程中,也就是inetinfo.exe這個程式。所以當inetinfo.exe進程崩潰時,這些資訊也就丟失。另外,重起或者關閉IIS服務都會造成資訊的丟失。 

原因1: 
bin目錄中的檔案被改寫,asp.net有一種機制,為了保證dll重新編譯之後,系統正常運行,它會重新啟動一次網站進程,這時就會導致Session丟失,所以如果有access資料庫位於bin目錄,或者有其他檔案被系統改寫,就會導致Session丟失 

原因2: 
檔案夾選項中,如果沒有開啟“在單獨的進程中開啟檔案夾視窗”,一旦建立一個視窗,系統可能認為是新的Session會話,而無法訪問原來的Session,所以需要開啟該選項,否則會導致Session丟失 

原因3: 
似乎大部分的Session丟失是用戶端引起的,所以要從用戶端下手,看看cookie有沒有開啟 

原因4: 
Session的時間設定是不是有問題,會不會因為逾時造成丟失 

原因5: 
IE中的cookie數量限制(每個域20個cookie)可能導致session丟失 

原因6: 
使用web garden模式,且使用了InProc mode作為儲存session的方式 

解決丟失的經驗 
1. 判斷是不是原因1造成的,可以在每次重新整理頁面的時候,跟蹤bin中某個檔案的修改時間 
2. 做Session讀寫日誌,每次讀寫Session都要記錄下來,並且要記錄SessionID、Session值、所在頁面、當前函數、函數中的第幾次Session操作,這樣找丟失的原因會方便很多 
3. 如果允許的話,建議使用state server或sql server儲存session,這樣不容易丟失 
4. 在global.asa中加入代碼記錄Session的建立時間和結束時間,逾時造成的Session丟失是可以在SessionEnd中記錄下來的。 
5. 如果有些代碼中使用用戶端指令碼,如javascript維護Session狀態,就要嘗試調試指令碼,是不是因為指令碼錯誤引起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裡? 
答:這依賴使用的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屬性。然而,如果你使用Proxy 伺服器訪問Web Service由於架構的限制,兩者不能共用Session。 

問:當我使用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在global.asax中的那些事件中有效? 
答:Session只有在AcquireRequestState事件之後有效,該事件之後的事件都可以使用Session。 

問:為了可以順序訪問Session的狀態值,Session是否提供了鎖定機制? 
答:Session實現了Reader/Writer的鎖機制: 
當頁面對Session具有可寫功能(即頁面有 <%@ Page EnableSessionState="True" %>標記),此時直到請求完成該頁面的Session持有一個寫鎖定。 
當頁面對Session具有唯讀功能(即頁面有 <%@ Page EnableSessionState="ReadOnly" %>標記),此時知道請求完成該頁面的Session持有一個讀鎖定。 
讀鎖定將阻塞一個寫鎖定;讀鎖定不會阻塞讀鎖定;寫鎖定將阻塞所有的讀寫鎖定。這就是為什麼兩個架構中的同一個頁面都去寫同一個Session時,其中一個要等待另一個(稍快的那個)完成後,才開始寫。 

問:Session平滑逾時意味著什嗎? 
答:Session平滑逾時意味著只要你的頁面訪問(使用)了Session,逾時時間將被重新整理(可以理解為重新計時),即從該頁面請求開始,將重新計算逾時時間。但是,該頁面不能禁用Session。它會自動的訪問當前頁面的Session,重新整理逾時時間。 

問:在global.asax中的事件處理函數中Session為什麼無效? 
答:依賴於在哪個事件處理函數中使用Session,Session在AcquireRequestState事件之後才有效,該事件之後的所有事件處理函數都可以使用Session,之前的則不能。 

問:當我使用InProc模式儲存Session時,此時的Session是儲存在哪裡? 
答:不同的IIS的處理方式不同, 
當使用的是IIS5的時候Session是儲存在aspnet_wp.exe的進程空間裡的。 
當使用的是IIS6時,預設情況下所有的應用程式共用應用程式集區,Session儲存在w3wp.exe的進程空間中。 

問:當頁面出現錯誤後我的Session是否將被儲存?我需要在Session_End中處理一些清理工作,但是失敗了,為什嗎? 
答:Session_End只有在Session運行在InProc模式下才會被執行。Session_End使用的帳號是運行aspnet_wp背景工作處理序的帳號(這個可以在machine.config中設定)。因此,如果在Session_End方法裡,使用整合式安全性連結到SQL,它將使用aspnet_wp進程的帳號開啟連結,此時成功與否則依賴於你的SQL的安全性設定。 

問:在Session_End是我是否可以獲得有效HttpSessionState和HttpContext對象? 
答:你可以在這個方法中獲得HttpSessionState對象,可以直接使用Session來訪問即可。但是不能獲得HttpContext對象,因為該事件並沒有和任何請求相關聯,因此不存在內容物件。 

問:在SQLServer模式下使用Session,為什麼我的Session不到期? 
答:在SqlServer模式下,Session的到期是通過SQL Agent的註冊工作完成的,請檢查你的SQL Agent是否運行? 

問:當我設定EnableSessionState為“ReadOnly”後,但是我在InProc模式下依然可以修改Session的值,這是為什嗎? 
答:即使EnableSessionState標示為ReadOnly,但是在InProc模式下使用者依然可以編輯Session。唯一不同的是,在請求過程中Session將不會被鎖住。 

問:為什麼在切換成SQLServer模式後我的請求被掛起了? 
答:檢查在Session裡面是否都儲存的是可以儲存在SQLServer模式下的對象,即這些對象必須支援序列化。 

問:當Session設定成cookieless後會有什麼影響? 
答:當把cookieless設定成true時,主要會有下面的約束: 
1、在頁面中不能使用絕對連結 
2、在應用程式中在除了Http和Https之間的切換時需要完成一些其他的步驟。 
如果發送一個連結給其他人,此時的URL裡面將包含Session ID的資訊,所以兩個人將公用一個Session。  

註:
*p5:Session丟失 http://topic.csdn.net/u/20081208/14/c154543c-8e86-406b-82a2-d3cc6f736b0d.html


5、用戶端使用Cookieless的方式儲存Session資訊

      sessionState中的cookieless="false"改為:cookieless="true",這樣,用戶端的Session資訊就不再使用Cookie儲存了,而是將其通過URL儲存。關閉當前的IE,開啟一個新IE,重新訪問剛才的Web應用程式,瀏覽器地址就會變為 http://localhost/MyTestApplication/(ulqsek45heu3ic2a5zgdl245)/default.aspx中黑體標出的就是用戶端的Session ID。注意,這段資訊是由IIS自動加上的,不會影響以前正常的串連。 *p6

問:當Session設定成cookieless後會有什麼影響? 
答:當把cookieless設定成true時,主要會有下面的約束: 
1、在頁面中不能使用絕對連結 
2、在應用程式中在除了Http和Https之間的切換時需要完成一些其他的步驟。 
如果發送一個連結給其他人,此時的URL裡面將包含Session ID的資訊,所以兩個人將公用一個Session。 *p7

註:
*p6:[ASP.NET] Session 詳解  http://www.blueidea.com/tech/program/2004/1856.asp
*p7:Session丟失 http://topic.csdn.net/u/20081208/14/c154543c-8e86-406b-82a2-d3cc6f736b0d.html

 
6、Session.SessionID 固定

  • IsNewSession:取得值,指出工作階段是否以目前要求建立。

  • SessionID:取得工作階段的唯一工作階段識別項。

re: 因為Session在還沒裝物件之前, ID都不是固定的. 如果您賦予Session內容, ex: Session["xxx"]=123 , 您會發現ID就會固定. *p8

註:
*p8:[ASP.Net]Session.IsNewSession與Session.SessionID http://www.dotblogs.com.tw/yilinliu/archive/2009/04/24/8163.aspx

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.