在ASP.NET中,狀態的保持方法大致有:ApplicationState,SessionState,Cookie,設定檔,緩衝。
ApplicationState 的典型應用如儲存全域資料。
SessionState 的典型應用如購物車項目儲存。
Cookie 的典型應用如網站的個人化。
設定檔 的典型應用如儲存客戶賬戶資訊。
緩衝 的典型應用如儲存從資料庫擷取的資料。
相對來講,最不安全的是Cookie,因為它儲存在用戶端,會被使用者修改。其它另外幾種都只是在服務端,從來沒被傳送到用戶端,所以是安全的。但是對於
Session來說,因為涉及到一個SessionID的問題,如果不使用SSL(Secure Socket Layer)協議(https 就基於SSL)的話,可能發生 工作階段劫持問題。
當然,上面提到的一個狀態保持是一個比較廣義的狀態保持,真正能保持特定用戶端的狀態的,只有Cookie 與 Session 兩種,當然其它基於登入使用者的方式就不提了。
今天我先只學習Session吧,前幾天筆試時,Session 上吃了大虧。。。。。
Session可以在伺服器端保持一些資訊,並且當一個特定的使用者在一個特定的WebApp中的不同頁面間跳轉時,這個資訊是可以共用的。所以,這種機制就常被拿來儲存購物車資訊,因為一個使用者在一個電子商務網站,可能會依次瀏覽不同的商品頁面,然後往裡面加商品,剛好是針對同一使用者的頁面跳轉資訊保持,正好用Session實現。
那麼對於Server端來說,要標識一個特定的用戶端,就要給用戶端一個ID,叫做 SessionID 。這個東西要由服務端產生然後發送,存放在用戶端,存放方式有兩種,一種是用戶端 Cookie ,另一種是附加在URL上。就是因為這個步驟,導致了前面所謂的工作階段劫持的風險。這種風險可由使用SSL傳送來解決。
關於SessionID,需要知道的是,它由HTTP REQUEST處理管道中的一個叫SessionStateModule的模組產生的 一個 120 位的標識符,並使用一個私人演算法來產生的,保證了該值是唯一的且足夠隨機(當然是從統計學的角度來說)。因此從這兒可以看出,SessionID完全不用開發人員操心,那是ASP.NET服務解決的問題。
接下來,系統提供了一個名叫 Session 的集合,可以直接進行讀寫操作,如下所示:
寫入:
Session["SimpleString"] = "Hello Session!";
在本頁面,或者下一個頁面中讀取:
string s = Session["SimpleString"].ToString(); //注意這兒要對集合元素進行類型轉化。
真是太簡單了。。。。
本著深入理解一樣事物的原則,我當然要弄明白,這個Session倒底是個什麼東西,以及這些Session資訊,倒底是放在伺服器上的哪兒的?
1:Session 是 HttpContext 類的一個屬性(Property),是一個HttpSessionState 類型的對象:
public sealed class HttpContext : IServiceProvider
{
//...
public HttpSessionState Session { get; }
//...
}
既然它是一個HttpSessionState類型的對象,那我看看這個類倒底提供了哪些東西可用,查了下MSDN,有很多東西,但我想比較有趣的有:
Session.Count 指示當前會話集合中的項目數。
Session.SessionID 指示當前用戶端工作階段的SessionID。
IsCookieless 指示當前會話ID是儲存在cookie中還是嵌入在URL中。
Timeout 指示了當前會話要儲存多長時間,因為用戶端不會請求銷毀Session資料,所以這些資料要等一定的時間後自動由服務端釋放。
Abandon() 使用該方法可以立即取消當前會話並釋放它戰勝的空間,在退出頁面中它很有效,能夠確保伺服器資源最快得到回收。
Clear() 該方法在不改變當前會話ID的情況下清空所有的會話項目。
2:Session資料也是由SessionStateModule這個模組來負責處理的,但它並不儲存會話資料,資料是放在稱做 SessionState Provider 的東西中的,有三種典型的Provider 方式: InProc ,StateServer ,SQLServer 。
InProc: 設定為將Session儲存在進程內,跟ASP中的儲存方式一樣,這是預設值。
StateServer :設定為將Session儲存在獨立的狀態服務中。
SQLServer: 設定將Session儲存在SQL Server中。
我們一般預設使用InProc方式,這個配置是通過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"
/>
這一個配置節的文法如下:
<sessionState mode="Off|InProc|StateServer|SQLServer"
cookieless="true|false"
timeout="number of minutes"
stateConnectionString="tcpip=server:port"
sqlConnectionString="sql connection string"
stateNetworkTimeout="number of seconds"
/>
另外兩種儲存方法要具體配置,參考下面的那篇列舉的文章即可。
最後一個學習點:Session資訊什麼情況下會不可用。
1:使用者關閉並重啟瀏覽器,這時候再請求同一個頁面,儘管Session仍然在,但是因為這次又產生了新的SessionID,所以舊的Session已經不可用了。
2:使用者通過另一個瀏覽器視窗訪問在同一頁面,這時候不同的瀏覽器有不同的處理方法,有些Session仍然可用,有些不可用。
3:由於沒有活動導致會話逾時,預設情況下是20分鐘閑置後就會逾時。
4:程式中調用了Session.Abandon()方法結束了會話。
相關好文:http://www.cnblogs.com/rayinuk/archive/2005/01/31/99670.html