http://blog.csdn.net/cityhunter172/archive/2006/05/14/727743.aspx
session的使用方法及實例。大家好,已有四個多月沒寫東東啦。今日抽空就說一下?Session?在?.Net v1.0/v1.1?中的存儲模式。大家可在?MSDN 2003?中搜索一下?<sessionState>?即可看到關于?Web.config?中的<sessionState>?節點元素的描述,共有?Off、InProc、StateServer、SQLServer?四種模式。Off、InProc?分別指“不啟用”、“進程內保存(默認值)”,此兩種模式沒啥講的,所謂?InProc?就是把?Session?保存在?aspnet_wp.exe?(Windows 2000?解析?ASP.NET頁面所用的進程)?或?w3wp.exe?(Win2003?的進程)?中,一旦進程被中止或被重置,Session?將丟失。
一、????????引發?Session?丟失的幾種原因
動過手寫代碼的人都知道,Session?丟失是比較常見的事。以下是本人這幾年所遇到的,能夠引發?Session?丟失的原因,不敢說是百分百,丟失概率還是特別高的。錯…,簡直可以說是“相…當…”高哇?^_^"
1、????存放?Session?的電腦重啟(廢話,若這樣都不丟,你神仙啊)
2、????InProc?模式:aspnet_wp.exe?或?w3wp.exe?在“任務管理器”中或其它情況下導致其進程被終止運行。
3、????InProc?模式:修改?.cs?文件后,編譯了兩次(只編譯一次,有時不會丟失)
4、????InProc?模式:修改了?Web.config
5、????InProc?模式,Windows 2003?環境:應用程序池回收、停止后重啟
6、????InProc?模式:服務器上?bin?目錄里的?.dll?文件被更新
以上列舉的都是?InProc?模式下,容易引發解析?ASP.NET?應用程序重置的原因。是不是覺得很窩火?之前我也有這種感覺,慢慢就習慣啦,再后來就干脆不用這種模式了。于是乎,就有了使用下列兩種模式的嘗試,現寫出來與大家一起分享。
二、????????使用?StateServer?保存?Session
StateServer?模式的實質是,把Session?存放在一個單獨的進程里,此進程獨立于?aspnet_wp.exe?或?w3wp.exe?。啟用此服務后,在“任務管理器”中可以看到一個名為?aspnet_state.exe?的進程,下面開始說明一下設置的具體步驟:
?
1、????修改注冊表(關鍵步驟,如下圖)
運行?regedit?→?打開注冊表?→?找到HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/aspnet_state/Parameters?節點?→?將?AllowRemoteConnection?的鍵值設置成“1”(1?為允許,0?代表禁止)→?設置?Port?(端口號)
注意事項:
???????a)、若ASP.NET State Service?正在運行,修改注冊表內容后,則需要重新啟動該服務
b)、注意端口號的鍵值是以十六進制儲存的,可以使用十進制進行修改,42424?是默認的端口
c)、AllowRemoteConnection?的鍵值設置成“1”后,意味著允許遠程電腦的連接,也就是說只要知道你的服務端口,就可享用你的ASP.NET State Service,即把?Session?存放在你的電腦進程內,因此請大家慎用;鍵值為“0”時,僅有stateConnectionString?為“tcpip=localhost:?42424”與“tcpip=127.0.0.1:42424”的情況,方可使用ASP.NET?State?Service
?
?
2、????開啟?ASP.NET State Service(如下圖)
右鍵點擊“我的電腦”→?管理?→?服務與應用程序?→?服務?→?雙擊“ASP.NET State Service”?→?啟動(可設為“自動”)
說明:只要安裝了?.Net Framework v1.0/v1.1?,都擁有此服務。
?
?
3、????更改?Web.config
打開?Web.config?→?找到?<sessionState>?節點內容
<sessionState
????????????mode="InProc"
????????????stateConnectionString="tcpip=127.0.0.1:42424"
????????????sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
????????????cookieless="false"
????????????timeout="20"?/>
?
→?將其改為以下內容
<sessionState?mode="StateServer"??stateConnectionString="tcpip=192.168.0.2:42424"?timeout="20"?/>
注意事項:
???????a)、設成StateServer?后,必須要有對應的stateConnectionString
???????b)、注意?IP?地址(可以是遠程計算機?IP、計算機名稱、域名)與端口號,端口號需與ASP.NET State Service?的服務端口一致
?
三、????????將?Session?放入?SQLServer?保存
SQLServer?模式就是,把Session?存放在?SQL Server?數據庫里(注意不是?Oracle?,動動腳趾都能猜到原因啦),下面開始說明一下設置的具體步驟:
?
1、????啟動相關的數據庫服務(如圖)
運行SQL Server?服務管理器?→?啟動?SQL Server?(最好設為開機自動運行)?→?啟動?SQL Server Agent?服務(最好設為開機自動運行)
注意事項:
???????a)、注意啟動順序,也可通過下列方式設置:?右鍵點擊“我的電腦”→?管理?→?服務與應用程序?→?服務?→?找到“MSSQLSERVER”與“SQLSERVERAGENT”?→?啟動并設置啟動類型為“自動”
b)、SQL Server Agent在此處的作用是清除數據庫中已過期的?Session
?
?
?
2、????建立存放?Session?的?DataBase
運行“SQL?查詢分析器”→?使用“sa”或是擁有“master”的?db_owner?權限的用戶登錄數據庫?→?打開查詢文件?C:/WINNT/Microsoft.NET/Framework/v1.1.4322/InstallSqlState.sql?(存放在?Windows?系統目錄的?.Net?安裝目錄下可找到)?→?直接運行該?sql?腳本?→?刷新數據庫即可看到名為?ASPState?的?DataBase
?
?
?
3、????建立連接數據庫?ASPState?的用戶,并為此用戶授權(此步驟可跳過)
進行此步的原因是:一是不想在?Web.config?中出現?sa?的密碼;二是?tempdb?在數據庫啟動后僅保留?sa?一個帳號的使用權限,其余帳號的權限統統被清除,但保存?Session又需要用到此?DataBase;
?
A)、運行?SQL Server?的企業管理器?→?展開數據庫的安全性?→?右擊“登錄”?→?新建“登錄”?→?輸入“名稱”?→?選擇?“SQL Server?身份驗證”?→?輸入“密碼”?→?指定“數據庫”?→?點擊“數據庫訪問”?→?勾選?“ASPState”?→?選中“db_owner”角色?→?點擊“確定”?→?再一次輸入“密碼”?→?點擊“確定”?后即可建立?ASPState?的用戶(此處建立名為“SessionStateUser”,密碼為“123456”的測試用戶)
?
?????
?
?
B)、運行?SQL Server?的企業管理器?→?展開“管理”?→?展開“SQL Server?代理”?→?右擊“作業”?→?點擊“新建作業”?→?輸入?“名稱”(此例為?GrantSessionUser?)?→?點擊標簽?“步驟”?→?新建?→?輸入?“步驟名”(此例為?Grant01)?→?選擇數據庫“tempdb”?→?編寫?SQL?腳本“execsp_adduser?'SessionStateUser',?'SessionUser'?,'db_owner'?”→?確定?→?點擊標簽?“調度”?→?新建?→?輸入?“名稱”(此例為?Start01?)→?選擇類型“SQL Server?代理啟動時自動啟動”?→?確定?→?最后點擊“確定”新增完畢
?
?
?
?
C)、也可運行以下腳本一次性搞定以上?A、B?兩個步驟
/******腳本開始******/
??????--新建數據庫帳號?SessionStateUser?,默認登錄?ASPState
EXEC?sp_addlogin?'SessionStateUser',?'123456',?'ASPState'
?
use?ASPState????????--切換?DataBase
?
??????--將?SessionStateUser?授予?db_owner?的權限
exec?sp_adduser?'SessionStateUser',?'SessionUser'?,'db_owner'
?
use?master????????????--切換?DataBase
?
BEGIN TRANSACTION??
??????/******聲明變量******/????????
????DECLARE?@JobID?BINARY(16)?
????DECLARE?@ReturnCode?INT???
????SELECT?@ReturnCode?=?0????
?
????--?若沒有,則添加作業的分類
????IF?(SELECT?COUNT(*)?FROM?msdb.dbo.syscategories?WHERE?name?=?N'[Uncategorized (Local)]') <?1
????????EXECUTE?msdb.dbo.sp_add_category @name?=?N'[Uncategorized (Local)]'
?
????--?新建作業
????EXECUTE?@ReturnCode?=?msdb.dbo.sp_add_job???--調用存儲過程?sp_add_job
????????????@job_id?=?@JobID?OUTPUT,???????????--將返回的?JobID,賦值給變量
????????????@job_name?=?N'GrantSessionUser',???--作業名稱
????????????@owner_login_name?= NULL,???????????--默認為當前用戶所有
????????????@description?=?null,
????????????@category_name?=?N'[Uncategorized (Local)]',????????--作業分類歸屬
????????????@enabled?=?1,????????????????????--是否啟用
????????????@notify_level_email?=?0,
????????????@notify_level_page?=?0,
????????????@notify_level_netsend?=?0,
????????????@notify_level_eventlog?=?0,
????????????@delete_level=?0
?
????IF?(@@ERROR?<>?0?OR?@ReturnCode?<>?0)?GOTO?QuitWithRollback?--出錯則回滾
???
????--?新建步驟
????EXECUTE?@ReturnCode?=?msdb.dbo.sp_add_jobstep?--調用存儲過程?sp_add_jobstep
????????????@job_id?=?@JobID,???????????????????--傳入剛剛新建的?JobID
????????????@step_id?=?1,
????????????@step_name?=?N'Grant01',?????????--步驟名稱
????????????@command?=?N'exec sp_adduser ''SessionStateUser'', ''SessionUser'' ,''db_owner''',
?????????????--需要執行的?SQL?腳本(注意用兩個連續的單引號表示?SQL?中的單引號)
?
????????????@database_name?=?N'tempdb',?--執行上述?SQL?所用的?DataBase
????????????@server?=?N'',
????????????@database_user_name?=?N'',
????????????@subsystem?=?N'TSQL',????--執行類型為“Transact-SQL?腳本”
????????????@cmdexec_success_code?=?0,
????????????@flags?=?0,
????????????@retry_attempts?=?0,
????????????@retry_interval?=?1,
????????????@output_file_name?=?N'',
????????????@on_success_step_id?=?0,
????????????@on_success_action?=?1,
????????????@on_fail_step_id?=?0,
????????????@on_fail_action?=?2
?
????IF?(@@ERROR?<>?0?OR?@ReturnCode?<>?0)?GOTO?QuitWithRollback
???
????--?新建調度
????EXECUTE?@ReturnCode?=?msdb.dbo.sp_add_jobschedule
????????????@job_id?=?@JobID,
????????????@name?=?N'Start01',???--調度名稱
????????????@enabled?=?1,
????????????@freq_type?=?64???????????????--“64”表示?當?SQLServerAgent?服務啟動時運行
?
????IF?(@@ERROR?<>?0?OR?@ReturnCode?<>?0)?GOTO?QuitWithRollback
???
????--?將新建的作業添加到本地數據庫
????EXECUTE?@ReturnCode?=?msdb.dbo.sp_add_jobserver?@job_id?=?@JobID,?@server_name?=?N'(local)'
????IF?(@@ERROR?<>?0?OR?@ReturnCode?<>?0)?GOTO?QuitWithRollback
???
????COMMIT?TRANSACTION?????????
????GOTO???EndSave?????????????
QuitWithRollback:
????IF?(@@TRANCOUNT?>?0)?ROLLBACK?TRANSACTION
EndSave:
/******腳本結束******/
?
4、????設置?Web.config?內容
打開?Web.config?→?找到?<sessionState>?節點內容?→?修改為以下內容即可:
<sessionState?mode="SQLServer"??sqlConnectionString?="data source=192.168.0.2; user id=?SessionStateUser; password=123456"?timeout="20"?/>
注意事項:
???????a)、sqlConnectionString?中不能出現?initial catalog?選項
b)、SQL Server Agent在此處的作用是清除數據庫中已過期的?Session
c)、你若跳過了第三步,則?user id?需要用?sa?進行登錄
d)、若sqlConnectionString?為?“data source=127.0.0.1;Trusted_Connection=yes”,則使用本地計算機ASPNET(Windows 2000?系統帳戶)或?Network Service(Windows 2003?系統帳戶)的身份登錄數據庫。要是數據庫不允許上述用戶登錄,則報錯;同樣,即使上述帳戶能成功登錄,也要分配其?tempdb?的權限,理由是?Session?是保存在?tempdb?中的,若沒有該?DataBase?的存取權限是行不滴。見下圖:
?
?