理解Session State模式+ASP.NET SESSION丟失
理解Session State模式+ASP.NET SESSION丟失FAQ [翻譯]
作者:Patrick Y. Ng
原文地址:http://forums.asp.net/7504/ShowPost.aspx
譯者:Tony Qu (來自BluePrint翻譯團(tuán)隊(duì))
原文最后一次更新:2004年9月21日
本文被分成兩部分:
1.“理解Session State模式”——幫助你理解三種Session State的不同之處
2. FAQ
1.理解Session State模式
存儲(chǔ)位置
InProc:session在服務(wù)器中以活動(dòng)對(duì)象方式存儲(chǔ)(aspnet_wp.exe)
StateServer: session被序列化并保存在單獨(dú)的aspnet_state.exe的內(nèi)存中。StateServer能夠運(yùn)行在另一臺(tái)服務(wù)器上
SQLServer: session被序列化并保存在SQL Server中
性能:
InProc:最快,但是session數(shù)據(jù)越多,web服務(wù)器上消耗的內(nèi)存也越多,它可能影響性能。
StateServer:當(dāng)存儲(chǔ)基本類型(如string,integer等)數(shù)據(jù)時(shí),在同一個(gè)測試環(huán)境中它比InProc慢15%。如果你存儲(chǔ)大量對(duì)象,序列化和反序列化可能影響到性能
SQLServer:當(dāng)存儲(chǔ)基本類型(如string,integer等)數(shù)據(jù)時(shí),在同一個(gè)測試環(huán)境中它比InProc慢25%。它也有與StateServer一樣的序列化性能問題。
關(guān)于Out-of-Proc(OOP,非InProc)模式的性能提示
如果你使用OOP模式(即StateServer或SQLServer),session state中的序列化和反序列化對(duì)象將成為你的主要性能消耗之一。對(duì)于基本類型,ASP.NET通過一種內(nèi)部優(yōu)化方法來完成序列化和反序列化。(基本類型包括所有的數(shù)字類型(如Int, Byte, Decimal,String, DateTime, TimeSpan, Guid, IntPtr和UIntPtr等))
如果你有一個(gè)session變量(如一個(gè)ArrayList對(duì)象),且它不是一個(gè)基本類型,ASP.NET將使用BinaryFormatter來進(jìn)行序列化和反序列化,那可能會(huì)相對(duì)慢一些。
所以出于性能考慮,最好使用上面列出的基本類型來存儲(chǔ)所有的session state數(shù)據(jù)。例如,如果你需要存儲(chǔ)兩個(gè)東西,名字和地址,在session state中你既可以(方法a)使用兩個(gè)string session變量來存儲(chǔ)它們,也可以(方法b)創(chuàng)建一個(gè)內(nèi)含兩個(gè)string的類來保存它們,然后把這個(gè)類對(duì)象保存在一個(gè)session變量中。出于性能考慮,你應(yīng)該選擇方法a。
為了進(jìn)一步理解這個(gè)主題,請(qǐng)看FAQ中的一個(gè)問題:“序列化和反序列化如何在SqlServer和StateServer模式下工作”
健壯性
InProc:如果工作者進(jìn)程(aspnet_wp.exe)進(jìn)行資源回收或者應(yīng)用程序域(appdomain)重啟動(dòng),session state就會(huì)丟失。這是因?yàn)閟ession state是保存在一個(gè)應(yīng)用程序域的內(nèi)存空間中的。對(duì)配置文件(如web.config和machine.config)的修改或者\(yùn)bin目錄的任何改變(例如在你使用VS編譯應(yīng)用程序后產(chǎn)生了一個(gè)新的dll)都可能引起重啟動(dòng),詳細(xì)請(qǐng)見KB324772。在1.0中,也有一個(gè)bug可能引起工作者進(jìn)程重啟動(dòng),但這個(gè)bug在1.1中已經(jīng)修復(fù),見KB321792。
如果你使用的是IIS6.0,你可以在IIS Manager中找到Application Pools/DefaultAppPool,其中可以看到回收(Recycling)選項(xiàng)卡與性能(Performace)選項(xiàng)卡中是否有引起IIS工作者進(jìn)程(w3svc.exe)停止工作的參數(shù)。
更多有關(guān)應(yīng)用程序資源回收的內(nèi)容,可以看我的另一篇FAQ:
http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=232621
StateServer:解決了InProc模式的session state丟失問題。允許一個(gè)webfarm在中央服務(wù)器中存儲(chǔ)session。只能在State Server上出現(xiàn)失敗。
SQLServer:與StateServer相似。session state的數(shù)據(jù)在SQL Server重啟后仍然保留著,你也可以按照KB311209的步驟使用SQL server failover cluster
警告
InProc:它不能在web garden模式下工作,因?yàn)樵谶@個(gè)模式下會(huì)有多個(gè)aspnet_wp.exe在同一臺(tái)機(jī)器上運(yùn)行。建議在使用web garden使切換到State Server或SQL Server。僅在InProc模式下支持Session_End事件。
StateServer
- 在web farm中,請(qǐng)確認(rèn)在所有的web服務(wù)器上有相同的<machineKey>。KB313091描述了如何設(shè)置它。
- 請(qǐng)確保你的對(duì)象是可序列化的。詳見KB312112
- 為了在web farm中的不同web服務(wù)器上維護(hù)session state,IIS Metabase中的網(wǎng)站應(yīng)用程序路徑(如\LM\W3SVC\2)應(yīng)該在所有的服務(wù)器上保持一致(大小寫敏感)。詳見KB325056
SQLServer
- 在1.0中有一個(gè)bug,如果你在連接字符串中指定integrity security(如"trusted_connection=true"或 "integrated security=sspi"),且你打開了asp.net的身份模擬,它將不會(huì)工作。這個(gè)問題在KB324479中有描述,不幸的是這份文檔中的描述和原因部分是錯(cuò)誤的。不過已經(jīng)有一個(gè)QFE fix對(duì)它作了修復(fù),這個(gè)fix將包含在1.0 sp3中。這個(gè)問題在1.1中已經(jīng)修復(fù)了。
- 請(qǐng)確認(rèn)你的對(duì)象是可序列化的,否則你的請(qǐng)求可能被掛住,詳見KB312112。SQLServer模式的掛起問題已經(jīng)在1.1中修復(fù),KB324479的QFE fix也修復(fù)了這個(gè)問題。1.0 sp3也對(duì)這個(gè)問題作了修復(fù)。
- 為了在web farm中的不同web服務(wù)器上維護(hù)session state,IIS Metabase中的網(wǎng)站應(yīng)用程序路徑(如\LM\W3SVC\2)應(yīng)該在所有的服務(wù)器上保持一致(大小寫敏感)。詳見KB325056
其他資源
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/aspnetsessionstate.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/CachingArchch2.asp
http://www.411asp.net/home/tutorial/specific/web/sessions
2. FAQ問題列表
Q: session state在部分瀏覽器上工作,而在其他一些上不工作。為什么呢?
Q: 在InProc模式中,為什么我有時(shí)會(huì)丟失所有的session?
Q: session state在一些web服務(wù)器上工作,但是在其他服務(wù)器上不工作。
Q: 為什么session state不可用?
Q: 為什么session_end沒有觸發(fā)?
Q: 使用InProc模式時(shí),為什么我的session變量頻繁丟失?
Q: 在session超時(shí)或刪除之后,為什么SessionID保持不變
Q: 為什么SessionID每一次請(qǐng)求都會(huì)改變
Q: Session.Abandon()和Session.Clear()有什么區(qū)別
Q: session的Timeout屬性是一個(gè)滑動(dòng)超時(shí)值嗎?
Q: 我可以在ASP.NET和ASP之間共享session嗎?
Q: 我可以在web應(yīng)用程序(例如虛擬目錄或者IIS的應(yīng)用程序)間共享session state嗎?
Q: 在session state中可以存儲(chǔ)哪些類型的對(duì)象?
Q: 為什么我的請(qǐng)求在切換到SQLServer模式之后掛住了?
Q: 為什么Response.Redirect和Server.Transfer在Session_End中不工作?
Q: 在Session_End中,我可以獲得一個(gè)有效的HttpSessionState對(duì)象和HttpContext對(duì)象嗎?
Q: 在web service中如何使用session?
Q:我正在寫一個(gè)HttpHandler,為什么session stae不工作?
Q: 我正在使用web farm,并且每當(dāng)我重定向到其他服務(wù)器時(shí),session state就會(huì)丟失?
Q: 如果使用cookieless,我該如何從一個(gè)HTTP頁面重定向到一個(gè)HTTPS頁面?
Q: session state有沒有一個(gè)鎖機(jī)制來安排對(duì)session的訪問順序?
Q: 我該如何檢測一個(gè)session過期,然后重定向到另一個(gè)頁面
Q: 在Session_End中,我嘗試使用SQL做一些清理工作,但是失敗了,請(qǐng)問為什么?
Q: 我使用的是SQLServer模式,為什么我的session不會(huì)過期
Q: 我有一個(gè)以htm為擴(kuò)展名的frameset頁面,并且我發(fā)覺其中包含的每個(gè)幀在第一次請(qǐng)求時(shí)都有一個(gè)不同的SessionID,這是為什么?
Q: 我將EnableSessionState設(shè)置為ReadOnly,但是在InProc模式下,我仍然可以修改session,為什么?
Q: 我將cookieless設(shè)置為true,在Redirect之后session變量丟失了,為什么?
Q: 將cookieless設(shè)置為true有哪些缺點(diǎn)
Q: 在InProc模式下,我用編程方式改變了session的超時(shí)時(shí)間,它觸發(fā)了Session_End,為什么?
Q: 在SQLServer模式下,我可以把session state保存在除tempdb之外的數(shù)據(jù)庫中嗎?
Q: 如何防止將未加密的字符串放在我的連接字符串匯總?
Q: 在使用SQLServer模式時(shí),我需要怎樣的SQL權(quán)限?
Q: 我可以自己寫定制的session state模式嗎?
Q: 在SQLServer或StateServer模式下,序列化和反序列化如何工作?
Q: 我該如何讓我的state server更安全?
Q: 我能否可以使用非global.asax中的處理程序來訂閱SessionStateModule.End事件?
Q: 不同的應(yīng)用程序可以把他們的session state保存在同一個(gè)SQL Server上的不同數(shù)據(jù)庫中嗎?
Q: session state在部分瀏覽器上工作,而在其他一些上不工作。為什么呢?
A: 估計(jì)你沒有使用cookieless,你必須保證你的瀏覽器支持cookie。請(qǐng)參考這份KB:http://support.microsoft.com/default.aspx?scid=kb;EN-US;q316112
Q: 在InProc模式中,為什么我有時(shí)會(huì)丟失所有的session?
A: 請(qǐng)見理解session state模式的健壯性部分
Q: session state在一些web服務(wù)器上工作,但是在其他服務(wù)器上不工作。
A: 可能是機(jī)器名的問題,見http://support.microsoft.com/default.aspx?scid=kb;EN-US;q316112
Q: 為什么session state不可用?
A:
- 首先,檢查web.config、machine.config和Page標(biāo)簽來確認(rèn)你啟用了session state
參考資料:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconsessionstate.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconpage.asp
- 請(qǐng)注意session state并非在任何地方、任何時(shí)間都可以使用,它僅在HttpApplication.AcquireRequestState事件之后可用。例如,在 global.asax中的Application_OnAuthenticateRequest處理程序中,session state不可用
- 請(qǐng)確認(rèn)System.Web.SessionState.SessionStateModule已包含在配置文件的< httpModules>節(jié)中。一個(gè)常見的例子是,出于性能考慮,SharePoint應(yīng)用程序會(huì)把這個(gè)模塊從web.config文件中移除,因此導(dǎo)致session不可用
Q: 為什么session_end沒有觸發(fā)?
A: 這是最常見的問題之一
1. 請(qǐng)記住session_end僅在InProc模式中可用
2. 關(guān)閉瀏覽器,session_end是不會(huì)觸發(fā)的。HTTP是一種無狀態(tài)協(xié)議,服務(wù)器沒有辦法知道你的瀏覽器是否已經(jīng)關(guān)閉。
3. 當(dāng)有n分鐘(n=timeout值)的無操作或調(diào)用Session.Abandon時(shí),Session_End才會(huì)觸發(fā)
4. 對(duì)于情況1而言,Session_End將由一個(gè)后臺(tái)線程觸發(fā),這表示:
a. Session_End中的代碼使用工作者進(jìn)程賬號(hào)運(yùn)行,如果你訪問如數(shù)據(jù)庫這樣的資源時(shí),可能會(huì)有權(quán)限問題。
b. 如果在Session_End中發(fā)生錯(cuò)誤,程序不會(huì)通知發(fā)生了什么
5. 對(duì)于情況2而言,為了讓Session_End觸發(fā),session state必須先存在。這意味著你必須在session state中存儲(chǔ)一些數(shù)據(jù),并且已經(jīng)完成了至少一個(gè)請(qǐng)求
6. 還是對(duì)于情況2而言,Session_End僅在被丟棄的session被找到的時(shí)候才會(huì)觸發(fā)。這樣的話,如果你在同一個(gè)請(qǐng)求中創(chuàng)建并丟棄一個(gè) session,由于session沒有被保存,因此也不會(huì)被找到,Session_End將不會(huì)被調(diào)用。這是v1.0和v1.1中的bug。
Q: 使用InProc模式時(shí),為什么我的session變量頻繁丟失?
A: 有可能是應(yīng)用程序資源回收引起的,見http://support.microsoft.com/default.aspx?scid=kb;en-us;Q316148
在v1.0中有一個(gè)bug可能會(huì)導(dǎo)致工作者進(jìn)程重啟動(dòng)。在v1.1和v 1.0sp2中已經(jīng)修復(fù)。見http://support.microsoft.com/default.aspx?scid=kb;EN-US;321792
關(guān)于應(yīng)用程序資源回收的詳細(xì)信息,請(qǐng)見我的另一篇:FAQhttp://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=232621
Q: 在session超時(shí)或刪除之后,為什么SessionID保持不變
A: 盡管在超時(shí)周期之后session state過期,sessionID將一直保持到瀏覽器session過期為止,也就是說,一個(gè)相同的sessionID可以有多次session超時(shí),但是始終對(duì)應(yīng)著一個(gè)相同的瀏覽器實(shí)例。
Q: 為什么SessionID每一次請(qǐng)求都會(huì)改變
A: 如果你的應(yīng)用程序從未在session state中存儲(chǔ)過數(shù)據(jù)。在這種情況下,那么每次請(qǐng)求都會(huì)創(chuàng)建一個(gè)新的session state(ID也是新的),但是不會(huì)被存儲(chǔ),因?yàn)槔锩媸裁磾?shù)據(jù)都沒有。
盡管如此,有兩種例外可能產(chǎn)生相同的Session ID
- 如果用戶使用相同的瀏覽器實(shí)例來請(qǐng)求另一個(gè)使用session state的頁面,那么你每次獲得的Session ID是相同的。詳見“在session超時(shí)或刪除之后,為什么SessionID保持不變?”
- 如果使用了Session_OnStart事件,即使session為空,asp.net也會(huì)保存session state。
Q: Session.Abandon()和Session.Clear()有什么區(qū)別
A: 主要的區(qū)別在于,如果你調(diào)用Session.Abandon(), Session_End將被觸發(fā)(僅在InProcxi下適用),在下一個(gè)請(qǐng)求中,Session_Start觸發(fā)。而Session.Clear()僅僅是清除數(shù)據(jù),但沒有刪除session。
Q: session的Timeout屬性是一個(gè)滑動(dòng)超時(shí)值嗎?
A: Session的Timeout是一個(gè)滑動(dòng)過期時(shí)間,意思是一旦你的頁面訪問session state,過期時(shí)間就會(huì)向挪。注意,只要頁面沒有被禁用,在請(qǐng)求時(shí)頁面就會(huì)自動(dòng)訪問session
Q: 我可以在ASP.NET和ASP之間共享session嗎?
A:不可以。但是有一篇文章講到了如何來繞過這個(gè)問題:http://www.msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/ConvertToASPNET.asp
當(dāng)然也有一些第三方解決方案。
Q: 我可以在web應(yīng)用程序(例如虛擬目錄或者IIS的應(yīng)用程序)間共享session state嗎?
A:不能。
Q: 在session state中可以存儲(chǔ)哪些類型的對(duì)象?
A:這是由你使用的模式?jīng)Q定的
- 如果你使用的是InProc模式,存儲(chǔ)在session state中的對(duì)象是活對(duì)象,那么你就可以存儲(chǔ)你創(chuàng)建的任何對(duì)象
- 如果你使用的是SQLServer或State Server模式,當(dāng)處理一個(gè)請(qǐng)求時(shí),session state中的對(duì)象對(duì)象將被序列化和反序列化,所以請(qǐng)確認(rèn)你的對(duì)象都是可序列化的,而它們的類都作了可序列化標(biāo)記。如果沒有,session state將不會(huì)成功存儲(chǔ)。在v1.0中,有一個(gè)bug,當(dāng)這個(gè)問題發(fā)生時(shí),如果使用SQLServer模式,請(qǐng)求可能在不知情的情況下被掛起。掛起的問題在v1.1和v1.0 sp3中已經(jīng)修復(fù)。KB324479的QFE fix也包含了對(duì)這一問題的修復(fù)。
更多信息請(qǐng)見:http://support.microsoft.com/directory/article.asp?ID=KB;EN-US;q312112
Q: 為什么我的請(qǐng)求在切換到SQLServer模式之后掛住了?
A:請(qǐng)看問題“在session state中可以存儲(chǔ)哪些類型的對(duì)象?”的答案
Q: 為什么Response.Redirect和Server.Transfer在Session_End中不工作?
A:Session_End是在服務(wù)器內(nèi)部觸發(fā)的,它基于一個(gè)內(nèi)部的計(jì)時(shí)器。因此,在事件觸發(fā)時(shí),與任何HttpRequest對(duì)象無關(guān)。這也是為什么Response.Redirect 和Server.Transfer不工作的原因。
Q: 在Session_End中,我可以獲得一個(gè)有效的HttpSessionState對(duì)象和HttpContext對(duì)象嗎?
A: 你可以獲得httpSessionState對(duì)象,你可以使用'Session'來訪問該對(duì)象。但是你無法訪問HttpContext,因?yàn)檫@個(gè)事件和請(qǐng)求沒有任何關(guān)系。
Q: 在web service中如何使用session?
A: 需要在調(diào)用方使用一些技巧,你必須保存web服務(wù)使用的cookie。請(qǐng)見關(guān)于HttpWebClientProtocol.CookieContainer的MSDN文檔。
盡管如此,如果你是通過代理對(duì)象從你的頁面調(diào)用web服務(wù),由于架構(gòu)限制,web服務(wù)和你的頁面無法共享session state。
如果你通過redirect調(diào)用web服務(wù),這是可以完成的
Q:我正在寫一個(gè)HttpHandler,為什么session stae不工作?
A: 你的HttpHandler接口必須實(shí)現(xiàn)標(biāo)記接口IRequiresSessionState或IReadOnlySessionState,方能使用session state。
Q: 我正在使用web farm,并且每當(dāng)我重定向到其他服務(wù)器時(shí),session state就會(huì)丟失?
A: 為了在web farm中的不同服務(wù)器之間維護(hù)session state,IIS Metabase中的網(wǎng)站應(yīng)用程序路徑(例如 \LM\W3SVC\2)應(yīng)該在所有的web服務(wù)器上保持一致(大小寫敏感)。詳見KB325056
Q: 如果使用cookieless,我該如何從一個(gè)HTTP頁面重定向到一個(gè)HTTPS頁面?
A: 嘗試使用下面的代碼:
String originalUrl = "/fxtest3/sub/foo2.aspx";
String modifiedUrl = "https://localhost" + Response.ApplyAppPathModifier(originalUrl);
Response.Redirect(modifiedUrl);
Q: session state有沒有一個(gè)鎖機(jī)制來安排對(duì)session的訪問順序?
A:session state實(shí)現(xiàn)了讀寫鎖定機(jī)制:
- 對(duì)session state有寫權(quán)限(如<%@ Page EnableSessionState="True" %> )的頁面或幀將獲得這個(gè)session的寫鎖,直到請(qǐng)求結(jié)束。
- 對(duì)session state有讀權(quán)限(如<%@ Page EnableSessionState="ReadOnly" %> )的頁面或幀將獲得這個(gè)session的讀鎖,直到請(qǐng)求結(jié)束。
- 讀鎖會(huì)阻塞寫鎖;讀鎖不會(huì)阻塞讀鎖;寫鎖會(huì)阻塞所有的讀鎖和寫鎖
- 這也是為什么當(dāng)兩個(gè)幀同時(shí)擁有session的訪問權(quán)限時(shí),一個(gè)幀必須等待另一幀先完成
Q: 我該如何檢測一個(gè)session過期,然后重定向到另一個(gè)頁面
A: 這是經(jīng)常要遇到的問題,但不幸的是沒有很簡單的方法來完成它。我們將期待在一個(gè)主要版本中實(shí)現(xiàn)它。同時(shí),如果你使用cookie,你可以在cookie中存儲(chǔ)一個(gè)標(biāo)志,這樣你就可以區(qū)分新瀏覽器+新session及舊瀏覽器+過期session,下面的代碼在session過期時(shí)會(huì)重定向到一個(gè)過期頁面。
void Session_OnStart(Object sender, EventArgs e) {
HttpContext context = HttpContext.Current;
HttpCookieCollection cookies = context.Request.Cookies;
if (cookies["starttime"] == null) {
HttpCookie cookie = new HttpCookie("starttime", DateTime.Now.ToString());
cookie.Path = "/";
context.Response.Cookies.Add(cookie);
}
else {
context.Response.Redirect("expired.aspx");
}
}
Q: 在Session_End中,我嘗試使用SQL做一些清理工作,但是失敗了,請(qǐng)問為什么?
A: 首先,session_End僅在InProc模式下支持。
第二,Session_End是用運(yùn)行工作者進(jìn)程(aspnet_wp.exe)的帳號(hào)運(yùn)行的,這個(gè)賬號(hào)可以在machine.config中指定。因此,在你的Session_End中,如果使用integrity security連接SQL,它將使用工作者進(jìn)程賬號(hào)身份連接,這可能會(huì)引起登錄失敗,這要看你的SQL安全設(shè)置了。
Q: 我使用的是SQLServer模式,為什么我的session不會(huì)過期
A: 在SQLServer模式下,session過期是由SQL Agent使用一個(gè)注冊(cè)任務(wù)完成的,請(qǐng)確認(rèn)你的SQL Agent是否已經(jīng)運(yùn)行。
Q: 我有一個(gè)以htm為擴(kuò)展名的frameset頁面,并且我發(fā)覺其中包含的每個(gè)幀在第一次請(qǐng)求時(shí)都有一個(gè)不同的SessionID,這是為什么?
A: 原因是你的frameset頁面是一個(gè)htm文件而不是一個(gè)aspx頁面
在通常情況下,如果一個(gè)frameset頁為一個(gè)aspx文件,當(dāng)你請(qǐng)求該頁面時(shí),會(huì)首先發(fā)請(qǐng)求給web服務(wù)器,你會(huì)收到一個(gè)asp.net session cookie(其中保存著session id),然后瀏覽器會(huì)為frame發(fā)送一個(gè)單獨(dú)的請(qǐng)求,而每個(gè)請(qǐng)求將擁有相同的session id。
然而,因?yàn)槟愕捻撁媸且粋€(gè)htm文件,第一個(gè)請(qǐng)求就不會(huì)獲得任何session cookie,因?yàn)轫撁媸怯蒩sp處理的而非asp.net,然后瀏覽器會(huì)為每個(gè)幀發(fā)送單獨(dú)的請(qǐng)求。但是,這次每個(gè)單獨(dú)的請(qǐng)求將不會(huì)持有任何 session id,這樣的話每個(gè)幀將創(chuàng)建自己的session。這也是為什么你在每個(gè)幀中看到的session id都不同。最后一個(gè)請(qǐng)求將贏得勝利,因?yàn)樗鼘⒏采w前兩個(gè)請(qǐng)求寫入的cookie。如果你刷新一次,你將看到它們擁有了相同的session id。
這個(gè)行為是設(shè)計(jì)所決定的,簡單的解決方法就是將frameset頁面改稱aspx
Q: 我將EnableSessionState設(shè)置為ReadOnly,但是在InProc模式下,我仍然可以修改session,為什么?
A: 盡管那些EnableSessionState被設(shè)置為ReadOnly,但是在InProc模式中,用戶仍然可以修改session。唯一的區(qū)別在于session在請(qǐng)求中不會(huì)被鎖住,這一限制是設(shè)計(jì)所決定的。對(duì)于這一點(diǎn)沒有在msdn中提到我表示抱歉。
Q: 我將cookieless設(shè)置為true,在Redirect之后session變量丟失了,為什么?
A: 如果你使用的是cookieless,你必須使用相對(duì)路徑(如..\hello.aspx),而不是絕對(duì)路徑(如\foo\bar\hello.aspx)。如果你使用的是絕對(duì)路徑,ASP.NET不會(huì)將session id保存在url中。
Q: 將cookieless設(shè)置為true有哪些缺點(diǎn)
A: 設(shè)置cookieless=true表示一些潛在的規(guī)則,主要有:
1. 你不能在你的頁面中使用絕對(duì)路徑
2. 在http和https之間切換的話,你必須做一些額外的動(dòng)作
3. 如果你的客戶發(fā)送了一個(gè)鏈接到一個(gè)朋友,URL將包含session id,兩個(gè)用戶可以在同一時(shí)間使用相同的session id
Q: 在InProc模式下,我用編程方式改變了session的超時(shí)時(shí)間,它觸發(fā)了Session_End,為什么?
A: 這是InProc的一個(gè)bug。如果你更改session的timeout值為另一個(gè)值,Session_End將被調(diào)用(但不會(huì)調(diào)用Session_Start)。我們期待在v2.0中能夠修復(fù)這個(gè)錯(cuò)誤。
Q: 在SQLServer模式下,我可以把session state保存在除tempdb之外的數(shù)據(jù)庫中嗎?
A: 是的。見KB311209。
Q: 如何防止將未加密的字符串放在我的連接字符串匯總?
A: 見sql trusted connection或者將連接字符串以加密數(shù)據(jù)形式保存在注冊(cè)表中。詳情請(qǐng)見,KB329250和KB329290。
Q: 在使用SQLServer模式時(shí),我需要怎樣的SQL權(quán)限?
A: 調(diào)用者需要對(duì)下面的存儲(chǔ)過程擁有EXEC權(quán)限,
dbo.TempGetAppID
dbo.TempGetStateItem
dbo.TempGetStateItemExclusive
dbo.TempReleaseStateItemExclusive
dbo.TempInsertStateItemLong
dbo.TempInsertStateItemShort
dbo.TempUpdateStateItemLong
dbo.TempUpdateStateItemShort
dbo.TempUpdateStateItemShortNullLong
dbo.TempUpdateStateItemLongNullShort
dbo.TempRemoveStateItem
dbo.TempResetTimeout
在v1.1中,你也需要對(duì)下面的存儲(chǔ)過程擁有EXEC權(quán)限
dbo.TempGetStateItem2
dbo.TempGetStateItemExclusive2
請(qǐng)注意存儲(chǔ)過程的擁有者必須對(duì)session state表(dbo.ASPStateTempSessions和 dbo.ASPStateTempApplications)擁有SELECT/INSERT/UPDATE/DELETE 權(quán)限。通常,擁有者是執(zhí)行installsqlstate.sql(或者持久版本,見KB311209)的帳號(hào)來安裝sql session state需要的表、存儲(chǔ)過程、數(shù)據(jù)庫
也請(qǐng)注意,如果你的session state表在tempdb中(默認(rèn)情況下)如果你對(duì)SQL Server進(jìn)行資源回收,所有在這張表上的權(quán)限設(shè)置將丟失。
Q: 我可以自己寫定制的session state模式嗎?
A:(待翻譯)
Q: 在SQLServer或StateServer模式下,序列化和反序列化如何工作?
A: (待翻譯)
Q: 我該如何讓我的state server更安全?
A:如果state server和web server運(yùn)行在一臺(tái)機(jī)器上,通過設(shè)置HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ aspnet_state\Param ters\AllowRemoteConnection的dword項(xiàng)為0,可以讓state server僅在本地運(yùn)行。這樣就可以防止遠(yuǎn)程客戶端連見到state server上。這一特性在v1.1中可用,在v1.0 sp3中也有。
state server必須受防火墻保護(hù),以防止外部連接以保證真正安全。默認(rèn)的端口是TCP 42424,你可以設(shè)置HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ aspnet_state\Param ters\Port來改變它。如果是本地模式,除了127.0.0.1以外,屏蔽所有外來連接;如果是遠(yuǎn)程模式,顯式的禁用所有的地址,除了對(duì)wev服務(wù)器的連接。
使用IPSec是另一種保護(hù)state server的方式。
Q: 我能否可以使用非global.asax中的處理程序來訂閱SessionStateModule.End事件?
A: 答案是否定的。當(dāng)SessionStateModule觸發(fā)End事件時(shí),只有定義在global.asax中的方法才會(huì)被觸發(fā)
這是出于安全原因考慮的才對(duì)此進(jìn)行限制。假設(shè)asp.net允許用戶使用的其他的處理程序來處理End事件。在這種情況下,用戶通常使用一個(gè)頁面方法作為處理程序,當(dāng)你在事件訂閱時(shí)傳入處理程序,處理程序?qū)⑴c你的程序運(yùn)行在的HttpApplication實(shí)例關(guān)聯(lián)。請(qǐng)注意, HttpApplication實(shí)例會(huì)被回收來處理其他請(qǐng)求。這樣的話,當(dāng)End事件觸發(fā)時(shí),asp.net將調(diào)用處理程序,而與之關(guān)聯(lián)的 HttpApplication實(shí)例已經(jīng)被另一個(gè)請(qǐng)求所使用,這樣的情況將引發(fā)各種各樣的問題。為了避免這種危險(xiǎn),在v1.0中決定進(jìn)調(diào)用 Global.asax中定義的方法。希望你們都可以忍受這一限制。
Q: 不同的應(yīng)用程序可以把他們的session state保存在同一個(gè)SQL Server上的不同數(shù)據(jù)庫中嗎?
A: 答案是肯定的。詳情請(qǐng)見:http://support.microsoft.com/default.aspx?scid=kb;EN-US;836680
posted on 2012-07-30 13:01 ** 閱讀(1279) 評(píng)論(0) 編輯 收藏