天天看點

asp.net Session詳解(再轉)

閱讀本文章前,需要讀者對以下知識有所了解。否則,閱讀過程中會在相應的内容上遇到不同程度的問題。

懂得ASP/ASP.NET程式設計

了解ASP/ASP.NET的Session模型

了解ASP.NET Web應用程式模型

了解ASP.NET Web應用程式配置檔案Web.config的作用、意義及使用方法

了解Internet Information Services(以下簡稱IIS)的基本使用方法

了解如何在Microsoft SQL Server中建立一個資料庫。

Session是什麼呢?簡單來說就是伺服器給用戶端的一個編号。當一台WWW伺服器運作時,可能有若幹個使用者浏覽正在運正在這台伺服器上的網站。當每個使用者首次與這台WWW伺服器建立連接配接時,他就與這個伺服器建立了一個Session,同時伺服器會自動為其配置設定一個SessionID,用以辨別這個使用者的唯一身份。這個SessionID是由WWW伺服器随機産生的一個由24個字元組成的字元串,我們會在下面的實驗中見到它的實際樣子。

這個唯一的SessionID是有很大的實際意義的。當一個使用者送出了表單時,浏覽器會将使用者的SessionID自動附加在HTTP頭資訊中,(這是浏覽器的自動功能,使用者不會察覺到),當伺服器處理完這個表單後,将結果傳回給SessionID所對應的使用者。試想,如果沒有SessionID,當有兩個使用者同時進行注冊時,伺服器怎樣才能知道到底是哪個使用者送出了哪個表單呢。當然,SessionID還有很多其他的作用,我們會在後面提及到。

除了SessionID,在每個Session中還包含很多其他資訊。但是對于編寫ASP或ASP.NET的程式與來說,最有用的還是可以通過通路ASP/ASP.NET的内置Session對象,為每個使用者存儲各自的資訊。例如我們想了解一下通路我們網站的使用者浏覽了幾個頁面,我們可能在使用者可能通路到每個的頁面中加入:

<%

If Session("PageViewed") = ""Then

 Session("PageViewed") = 1

Else

 Session("PageViewed") = Session("PageViewed") + 1

End If

%>

通過以下這句話可以讓使用者得知自己浏覽了幾個頁面:

Response.Write("You have viewed " & Session("PageViewed") & " pages")

可能有些有些讀者會問:這個看似像是數組的Session(“..”)是哪裡來的?需要我定義嗎?實際上,這個Session對象是具有ASP解釋能力的的WWW伺服器的内建對象。也就是說ASP的系統中已經給你定義好了這個對象,你隻需要使用就行了。其中Session(“..”)中的..就好像變量名稱,Session(“..”)=$$$中的$$$就是變量的值了。你隻需要寫上句話,在這個使用者的每個頁面中都可以通路..變量中的值了。

其實ASP一共内建了7個對象,有Session、Application、Cookie、Response、Request、Server等。在其他的伺服器端腳本語言如JSP、PHP等中也有其類似的對象,隻是叫法或者使用方法上不太一樣。

目前ASP的開發人員都正在使用Session這一強大的功能,但是在他們使用的過程中卻發現了ASP Session有以下缺陷:

程序依賴性:ASP Session狀态存于IIS的程序中,也就是inetinfo.exe這個程式。是以當inetinfo.exe程序崩潰時,這些資訊也就丢失。另外,重起或者關閉IIS服務都會造成資訊的丢失。

Session狀态使用範圍的局限性:剛一個使用者從一個網站通路到另外一個網站時,這些Session資訊并不會随之遷移過去。例如:新浪網站的WWW伺服器可能不止一個,一個使用者登入之後要去各個頻道浏覽,但是每個頻道都在不同的伺服器上,如果想在這些WWW伺服器共享Session資訊怎麼辦呢?

Cookie的依賴性:實際上用戶端的Session資訊是存儲與Cookie中的,如果用戶端完全禁用掉了Cookie功能,他也就不能享受到了Session提供的功能了。

鑒于ASP Session的以上缺陷,微軟的設計者們在設計開發 ASP.NET Session時進行了相應的改進,完全克服了以上缺陷,使得ASP.NET Session成為了一個更加強大的功能。

有的ASP.NET程式員說:Web.config檔案?我從來沒有聽說過啊,可是我寫的程式不是也能很正常的運轉嗎?是的,你說得沒錯,沒有Web.config檔案程式是可以正常運作的。但是,如果你做了一個大型的網站,需要對整個網站做一些整體配置,例如整個網站的頁面使用何種語言編寫的、網站的安全認證模式、Session資訊存儲方式等,這時你就需要使用Web.config檔案了。雖然Web.config檔案中的某些選項是可以通過IIS配置的,但是如果在Web.config中也有相應的設定就會覆寫掉IIS中的配置。而且,Web.config檔案的最大的便利之處就是可以在ASP.NET頁面中通過調用System.web名字空間通路Web.config中的設定。

Web.config有兩種,分别是伺服器配置檔案和Web應用程式配置檔案,他們都名為Web.config。在這個配置檔案中會儲存目前IIS伺服器中網頁的使用哪種語言編寫的、應用程式安全認證模式、Session資訊存儲方式的一系列資訊。這些資訊是使用XML文法儲存的,如果想對其編輯,使用文本編輯器就行了。

其中伺服器配置檔案會對IIS伺服器下所有的站點中的所有應用程式起作用。在.NET Framework 1.0中,伺服器的Web.config檔案是存在:\WinNT\Microsoft.NET\Framework\v1.0.3705中的。

而Web應用程式配置檔案Web.config則儲存在各個Web應用程式中。例如:目前網站的根目錄\Inetpub\wwwroot,而目前的Web應用程式為MyApplication,則Web應用程式根目錄就應為:\Inetpub\wwwroot\MyApplication。如果你的網站有且隻有一個Web應用程式,一般說來應用程式的根目錄就是\Inetpub\wwwroot。如果想添加一個Web應用程式,在IIS中添加一個具有應用程式起始點的虛拟目錄就行了。這個目錄下的檔案及目錄将被視為一個Web應用程式。但是,這樣通過IIS添加Web應用程式是不會為你生成Web.config檔案的。如果想建立一個帶有Web.config檔案的Web應用程式,需要使用Visual Studio.NET,建立一個Web應用程式項目。

Web應用程式的配置檔案Web.config是可選的,可有可無。如果沒有,每個Web應用程式會使用伺服器的Web.config配置檔案。如果有,則會覆寫伺服器Web.config配置檔案中相應的值。

在ASP.NET中,Web.config修改儲存後會自動立刻成效,不用再像ASP中的配置檔案修改後需要重新啟動Web應用程式才能生效了。

打開某個應用程式的配置檔案Web.config後,我們會發現以下這段:

<sessionState

  mode="InProc"

  stateConnectionString="tcpip=127.0.0.1:42424"

  sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"

  cookieless="false"

  timeout="20"

/>

這一段就是配置應用程式是如何存儲Session資訊的了。我們以下的各種操作主要是針對這一段配置展開。讓我們先看看這一段配置中所包含的内容的意思。sessionState節點的文法是這樣的:

必須有的屬性是

屬性

選項

描述

mode

設定将Session資訊存儲到哪裡

Off

設定為不使用Session功能

InProc

設定為将Session存儲在程序内,就是ASP中的存儲方式,這是預設值。

StateServer

設定為将Session存儲在獨立的狀态服務中。

SQLServer

設定将Session存儲在SQL Server中。

可選的屬性是:

cookieless

設定用戶端的Session資訊存儲到哪裡

ture

使用Cookieless模式

false

使用Cookie模式,這是預設值。

timeout

設定經過多少分鐘後伺服器自動放棄Session資訊。預設為20分鐘

stateConnectionString

設定将Session資訊存儲在狀态服務中時使用的伺服器名稱和端口号,例如:"tcpip=127.0.0.1:42424”。當mode的值是StateServer是,這個屬性是必需的。

sqlConnectionString

設定與SQL Server連接配接時的連接配接字元串。例如"data source=localhost;Integrated Security=SSPI;Initial Catalog=northwind"。當mode的值是SQLServer時,這個屬性是必需的。

stateNetworkTimeout

設定當使用StateServer模式存儲Session狀态時,經過多少秒空閑後,斷開Web伺服器與存儲狀态資訊的伺服器的TCP/IP連接配接的。預設值是10秒鐘。

在我們上面的Session模型簡介中,大家可以發現Session狀态應該存儲在兩個地方,分别是用戶端和伺服器端。用戶端隻負責儲存相應網站的SessionID,而其他的Session資訊則儲存在伺服器端。在ASP中,用戶端的SessionID實際是以Cookie的形式存儲的。如果使用者在浏覽器的設定中選擇了禁用Cookie,那末他也就無法享受Session的便利之處了,甚至造成不能通路某些網站。為了解決以上問題,在ASP.NET中用戶端的Session資訊存儲方式分為:Cookie和Cookieless兩種。

ASP.NET中,預設狀态下,在用戶端還是使用Cookie存儲Session資訊的。如果我們想在用戶端使用Cookieless的方式存儲Session資訊的方法如下:

找到目前Web應用程式的根目錄,打開Web.Config檔案,找到如下段落:

這段話中的cookieless="false"改為:cookieless="true",這樣,用戶端的Session資訊就不再使用Cookie存儲了,而是将其通過URL存儲。關閉目前的IE,打開一個新IE,重新通路剛才的Web應用程式,就會看到類似下面的樣子:

其中,http://localhost/MyTestApplication/(ulqsek45heu3ic2a5zgdl245)/default.aspx中黑體标出的就是用戶端的Session ID。注意,這段資訊是由IIS自動加上的,不會影響以前正常的連接配接。

準備工作

為了您能更好的體驗到實驗現象,您可以建立一個叫做SessionState.aspx的頁面,然後把以下這些代碼添加到<body></body>中。

<scriptrunat="server">

Sub Session_Add(sender As Object, e As EventArgs)

   Session("MySession") = text1.Value

   span1.InnerHtml = "Session data updated! <P>Your session contains: <font color=red>" & \

            Session("MySession").ToString() & "</font>"

End Sub

Sub CheckSession(sender As Object, eAs EventArgs)

   If (Session("MySession")Is Nothing) Then

    span1.InnerHtml = "NOTHING, SESSION DATA LOST!"

   Else

    span1.InnerHtml = "Your session contains: <font color=red>" & \

             Session("MySession").ToString() & "</font>"

</script>

<formrunat="server"id="Form2">

   <inputid="text1"type="text"runat="server"name="text1">

   <inputtype="submit"runat="server"OnServerClick="Session_Add"

      value="Add to Session State" id="Submit1"name="Submit1">

   <inputtype="submit"runat="server"OnServerClick="CheckSession"

      value="View Session State" id="Submit2"name="Submit2">

</form>

<hrsize="1">

<fontsize="6"><spanid="span1"runat="server" /></font>

這個SessionState.aspx的頁面可以用來測試在目前的伺服器上是否丢失了Session資訊。

讓我們來回到Web.config檔案的剛才那段段落中:

當mode的值是InProc時,說明伺服器正在使用這種模式。

這種方式和以前ASP中的模式一樣,就是伺服器将Session資訊存儲在IIS程序中。當IIS關閉、重起後,這些資訊都會丢失。但是這種模式也有自己最大好處,就是性能最高。應為所有的Session資訊都存儲在了IIS的程序中,是以IIS能夠很快的通路到這些資訊,這種模式的性能比程序外存儲Session資訊或是在SQL Server中存儲Session資訊都要快上很多。這種模式也是ASP.NET的預設方式。

好了,現在讓我們做個試驗。打開剛才的SessionState.aspx頁面,随便輸入一些字元,使其存儲在Session中。然後,讓我們讓IIS重起。注意,并不是使目前的站點停止再開始,而是在IIS中本機的機器名的節點上點選滑鼠右鍵,選擇重新啟動IIS。(想當初使用NT4時,重新啟動IIS必須要重新啟動計算機才行,微軟真是@#$%^&)傳回到SessionState.aspx頁面中,檢查剛才的Session資訊,發現資訊已經丢失了。

首先,讓我們來打開管理工具->服務,找到名為:ASP.NET State Service的服務,啟動它。實際上,這個服務就是啟動一個要儲存Session資訊的程序。啟動這個服務後,你可以從Windows任務管理器->程序中看到一個名為aspnet_state.exe的程序,這個就是我們儲存Session資訊的程序。

然後,回到Web.config檔案中上述的段落中,将mode的值改為StateServer。儲存檔案後的重新打開一個IE,打開SessionState.aspx頁面,儲存一些資訊到Session中。這時,讓我們重起IIS,再回到SessionState.aspx頁面中檢視剛才的Session資訊,發現沒有丢失。

實際上,這種将Session資訊存儲在程序外的方式不光指可以将資訊存儲在本機的程序外,還可以将Session資訊存儲在其他的伺服器的程序中。這時,不光需要将mode的值改為StateServer,還需要在stateConnectionString中配置相應的參數。例如你的計算你是192.168.0.1,你想把Session存儲在IP為192.168.0.2的計算機的程序中,就需要設定成這樣:stateConnectionString="tcpip=192.168.0.2:42424"。當然,不要忘記在192.168.0.2的計算機中裝上.NET Framework,并且啟動ASP.NET State Services服務。

首先,還是讓我們來做一些準備工作。啟動SQL Server和SQL Server代理服務。在SQL Server中執行一個叫做InstallSqlState.sql的腳本檔案。這個腳本檔案将在SQL Server中建立一個用來專門存儲Session資訊的資料庫,及一個維護Session資訊資料庫的SQL Server代理作業。我們可以在以下路徑中找到那個檔案:

[system drive]\winnt\Microsoft.NET\Framework\[version]\

然後打開查詢分析器,連接配接到SQL Server伺服器,打開剛才的那個檔案并且執行。稍等片刻,資料庫及作業就建立好了。這時,你可以打開企業管理器,看到新增了一個叫ASPState的資料庫。但是這個資料庫中隻是些存儲過程,沒有使用者表。實際上Session資訊是存儲在了tempdb資料庫的ASPStateTempSessions表中的,另外一個ASPStateTempApplications表存儲了ASP中Application對象資訊。這兩個表也是剛才的那個腳本建立的。另外檢視管理->SQL Server代理->作業,發現也多了一個叫做ASPState_Job_DeleteExpiredSessions的作業,這個作業實際上就是每分鐘去ASPStateTempSessions表中删除過期的Session資訊的。

接着,我們傳回到Web.config檔案,修改mode的值改為SQLServer。注意,還要同時修改sqlConnectionString的值,格式為:sqlConnectionString="data source=localhost; Integrated Security=SSPI;",其中data source是指SQL Server伺服器的IP位址,如果SQL Server與IIS是一台機子,寫127.0.0.1就行了。Integrated Security=SSPI的意思是使用Windows內建身份驗證,這樣,通路資料庫将以ASP.NET的身份進行,通過如此配置,能夠獲得比使用userid=sa;password=密碼的SQL Server驗證方式更好的安全性。當然,如果SQL Server運作于另一台計算機上,你可能會需要通過Active Directory域的方式來維護兩邊驗證的一緻性。

同樣,讓我們做個試驗。向SessionState.aspx中添加Session資訊,這時發現Session資訊已經存在SQL Server中了,即使你重起計算機,剛才的Session資訊也不會丢失。現在,你已經完全看見了Session資訊到底是什麼樣子的了,而且又是存儲在SQL Server中的,能幹什麼就看你的發揮了,哈哈。

通過這篇文章,你可以看到在Session的管理和維護上,ASP.NET比ASP有了很大的進步,我們可以更加随意的挑選适合的方法了。對于企業級的應用來說,這無疑對于伺服器的同步、伺服器的穩定性、可靠性都是有利的。相信在強大的微軟支援下,新一代的電子商務平台将會搭建的更好!

同時,大家也會發現,在這個整個技術中包括了作業系統、Web服務及資料庫多種技術的整合。我相信,也許Windows沒有Unix穩定,IIS沒有Apache穩定,SQL Server也沒有Oracle強大,但是,誰可以将他們如此完美的關聯到一起呢?是以說,雖然微軟每一方面都不是太強,但是如果把微軟的東西都整合到一起,誰敢說他不強大呢?微軟就是微軟!

部落格園大道至簡

<a href="http://www.cnblogs.com/jams742003/" target="_blank">http://www.cnblogs.com/jams742003/</a>

轉載請注明:部落格園