服務(wù)熱線
153 8323 9821
Session又稱(chēng)為會(huì)話(huà)狀態(tài),是Web系統(tǒng)中最常用的狀態(tài),用于維護(hù)和當(dāng)前瀏覽器實(shí)例相關(guān)的一些信息。舉個(gè)例子來(lái)說(shuō),我們可以把已登錄用戶(hù)的用戶(hù)名放在Session中,這樣就能通過(guò)判斷Session中的某個(gè)Key來(lái)判斷用戶(hù)是否登錄,如果登錄的話(huà)用戶(hù)名又是多少。
我們知 道,Session對(duì)于每一個(gè)客戶(hù)端(或者說(shuō)瀏覽器實(shí)例)是“人手一份”,用戶(hù)首次與Web服務(wù)器建 立連接的時(shí)候,服務(wù)器會(huì)給用戶(hù)分發(fā)一個(gè) SessionID作為標(biāo)識(shí)。SessionID是一個(gè)由24個(gè)字符組成的隨機(jī)字符串。用戶(hù)每次提交頁(yè)面,瀏覽器都會(huì)把這個(gè)SessionID包含在 HTTP頭中提交給Web服務(wù)器,這樣Web服務(wù)器就能區(qū)分當(dāng)前請(qǐng)求頁(yè)面的是哪一個(gè)客戶(hù)端。那么,ASP.NET 2.0提供了哪些存儲(chǔ)SessionID的模式呢:
· Cookie(默認(rèn))。如果客戶(hù)端禁止了Cookie的使用,Session也將失效。
· URL。Cookie是否開(kāi)啟不影響Session使用,缺點(diǎn)是不能再使用絕對(duì)鏈接了。
前面說(shuō)了SessionID可以存儲(chǔ)在客戶(hù)端的Cookie或者URL中,那么Session真正的內(nèi)容存儲(chǔ)在哪里呢?ASP.NET 2.0對(duì)于Session內(nèi)容的存儲(chǔ)也提供了多種模式。
· InProc(默認(rèn))。Session存儲(chǔ)在IIS進(jìn)程中(Web服務(wù)器內(nèi)存)。
· StateServer。Session存儲(chǔ)在獨(dú)立的Windows服務(wù)進(jìn)程中(可以不是Web服務(wù)器)。
· SqlServer。Session存儲(chǔ)在SqlServer數(shù)據(jù)庫(kù)的表中(SqlServer服務(wù)器)。
雖然 InProc模式的Session直接存儲(chǔ)在Web服務(wù)器IIS進(jìn)程中,速度比較快,但是每次重新啟動(dòng)IIS都會(huì)導(dǎo)致Session丟失。利用后兩種模 式,我們就完全可以把Session從Web服務(wù)器中獨(dú)立出來(lái),從而減輕Web服務(wù)器的壓力,同時(shí)減少Session丟失的概率。
因此,SessionID存儲(chǔ)在客戶(hù)端(可以是Cookie或者URL),其他都存儲(chǔ)在服務(wù)端(可以是IIS進(jìn)程、獨(dú)立的Windows服務(wù)進(jìn)程或者SQL Server數(shù)據(jù)庫(kù)中)。
讓我們先來(lái)實(shí)踐一下如何使用Session,進(jìn)而回答第二個(gè)問(wèn)題:Session存儲(chǔ)的類(lèi)型限制。Session不需要進(jìn)行任何配置就可以使用(默認(rèn)是InProc模式并且依賴(lài)Cookie)。首先,在頁(yè)面上建立兩個(gè)按鈕。
在btn_WriteSession按鈕的Click事件處理方法中,寫(xiě)入兩個(gè)Session,一個(gè)是簡(jiǎn)單的字符串,另外一個(gè)是自定義的類(lèi)。
protected void btn_WriteSession_Click(object sender, EventArgs e)
{
Session["SimpleString"] = "編程快樂(lè)";
MyUser user = new MyUser();
user.sUserName = "小朱";
user.iAage = 24;
Session["CustomClass"] = user;
}
Session的使用非常簡(jiǎn)單,直接對(duì)某個(gè)Key的Session進(jìn)行賦值即可。自定義類(lèi)MyUser如下:
class MyUser
{
public string sUserName;
public int iAage;
public override string ToString()
{
return string.Format("姓名:{0},年齡:{1}", sUserName, iAage);
}
}
在這里,我們覆寫(xiě)了ToString()方法直接返回實(shí)例的一些信息。然后,雙擊btn_ReadSession按鈕來(lái)實(shí)現(xiàn)從Session中讀取數(shù)據(jù)的代碼:
protected void btn_ReadSession_Click(object sender, EventArgs e)
{
if (Session["SimpleString"]==null)
{
Response.Write("讀取簡(jiǎn)單字符串失敗
");
}
else
{
string s=Session["SimpleString"].ToString();
Response.Write(s + "
");
}
if (Session["CustomClass"]==null)
{
Response.Write("讀取簡(jiǎn)單自定義類(lèi)失敗
");
}
else
{
MyUser user=Session["CustomClass"] as MyUser;
Response.Write(user.ToString()+"
");
}
}
在每次讀取 Session的值以前請(qǐng)務(wù)必先判斷Session是否為空,否則很有可能出現(xiàn)“未將對(duì)象引用設(shè)置到對(duì)象的實(shí)例”的異常。我們看到,從Session 中讀出的數(shù)據(jù)都是object類(lèi)型的,我們需要進(jìn)行類(lèi)型轉(zhuǎn)化后才能使用。打開(kāi)頁(yè)面,先單擊寫(xiě)入Session按鈕,再單擊讀取Session按鈕,頁(yè)面輸 出如 圖12-1所示。
由此看來(lái),Session能存儲(chǔ)任意對(duì)象,是這樣嗎?現(xiàn)在得出這個(gè)結(jié)論還太早了一點(diǎn),因?yàn)槲覀儾](méi)有實(shí)踐過(guò)StateServer和SqlServer模式的Session。要把Session存儲(chǔ)在Windows服務(wù)進(jìn)程中需要進(jìn)行以下幾個(gè)步驟。
n 第1步是打開(kāi)狀態(tài)服務(wù)。依次打開(kāi)“控制面板”→“管理工具”→“服務(wù)”命令,找到ASP.NET狀態(tài)服務(wù)一項(xiàng),右鍵單擊服務(wù)選擇啟動(dòng),如圖12-2所示。
n 如果你正式?jīng)Q定使用狀態(tài)服務(wù)存儲(chǔ)Session前,別忘記修改服務(wù)為自啟動(dòng)(在操作系統(tǒng)重啟后服務(wù)能自己?jiǎn)?dòng))以免忘記啟動(dòng)服務(wù)而造成網(wǎng)站Session不能使用,如圖12-3所示,雙擊服務(wù)把服務(wù)的啟動(dòng)類(lèi)型設(shè)置為自動(dòng)。
服務(wù)正常啟動(dòng)后可以觀察任務(wù)管理器的進(jìn)程頁(yè),其中的aspnet_state.exe進(jìn)程就是狀態(tài)服務(wù)進(jìn)程,如圖12-4所示。
n 第2步,在system.web節(jié)點(diǎn)中加入: