在.Net平臺下進行CS軟件開發時,咱們常常遇到之後還要用到某些變量上次修改後的值,爲了簡單起見,不少人都習慣用static來定義這些變量,我也是。這樣很是方便,下一次調用某個函數時該變量仍然保存的是處理過的值,直接拿來用就能夠了。
如今轉入了BS軟件開發,咱們很天然地會沿用這種習慣。如在頁面中統計某個按鈕被按下的次數,先在類中OnClick事件的處理過程前定義一static變量times,則每次調用該按鈕的OnClick事件時,令times增1便可,很是方便:
[C#]:
...
static int times=0;
...
private void Button1_Click(object sender,EventArgs e)
{
}
在咱們慶幸如此方便之餘,咱們應該意識到,這樣會給咱們帶來嚴重的問題。安全
這還要從Asp.net的運行機制談起。在CS模式軟件開發過程當中,咱們一般不會關心應用程序是在哪裏運行的,變量存放在哪裏,客戶端程序就運行在客戶端,服務器端程序就運行在服務器端,通常狀況下,兩者除了數據庫中的數據外基本沒有其餘共享的東西。因此這時客戶端的用戶大可放心的使用static變量,由於它們就存放在客戶端程序中。
因而咱們就習慣的在作BS模式的頁面時也用static變量,卻不知Asp.net中的static已不一樣於CS中的static。緣由很簡單,就是由於在Asp.net中全部的用戶將使用同一個static變量。這就意味着每個使用該頁面的用戶對該變量的操做將會影響到其餘用戶。就 拿上面計數器的例子來講,假設times初試值爲0,由於此時只有咱們本身在使用這個頁面,固然不會有什麼問題,但若是有兩我的同時鏈接到這個頁面,若是 A單擊了Button1一次,則B刷新頁面後Label1將顯示1,若是B再單擊Button1一次,則times變成2,兩我的刷新頁面後就出現問題 了:A和B都會說,我明明只單擊了Button1一次,怎麼Label1就顯示我單擊了兩次哪?——這就是由於兩我的共用的是服務器上同一個times, 任何一我的對times的操做都會在使用該頁面的他人的瀏覽器中表現出來。問題就出在這裏。
怎麼辦哪?還好,除了傳統的Asp中的Session對象外,Asp.net提供了一個更好的ViewState對象。ViewState 對象用來保存頁面中的各類變量,甚至是對象。使用方法和HashTable相似,只要用變量名稱作索引,如ViewState["Var"],就能夠用存 取變量Var的值,而無論Var是普通變量,仍是對象,甚至是內存中的一張DataTable,太方便了。爲何能夠用ViewState而不能用static變量哪?緣由就是服務器端會爲每一個鏈接到該頁面的用戶分別創建一個ViewState,因此ViewState至關於頁面級的Session。這下咱們能夠放心地使用ViewState來存取須要暫寸的變量和對象了。
ViewState的用法很簡單,以下所示:函數
一、保存變量到ViewState中:
ViewState["times"]=times;//存放普通變量timespa
ViewState["Orders"]=dtOrders;//存放DataTable型對象dtOrders
二、讀出ViewState中的值:對象
times=(int)ViewState["times"];
dtOrders=(DataTable)ViewState["Orders"];
但值得注意的是
linq to Sql 所獲得的數據集不能保存在ViewState中,linq實體類只支持
看見了吧?就如此簡單!有的朋友會問讀出變量的值時爲何要進行強制類型轉換?這是由於當變量(不論是int型的普通變量times,仍是 DataTable型的對象dtOrders)被存放到ViewState中後,ViewState可無論你是普通變量仍是對象,通通按Object來對 待。因此當咱們取出存放在ViewState中的東西時,必定要轉換成相應的類型,不然就會報錯。而這一操做不用在用ViewState保存變量時進行, 系統會自動轉換。(注意ViewState括號中的字符串只是爲了標識不一樣變量的索引,用不着非要和變量同名)因此上面計數器的代碼應該這樣寫纔好:
這是否是說static型變量就沒用了哪?固然不是!在C#中用static聲明的類不用實例化直接使用。正是因爲全部用戶共享服務器端的同一個 static變量,因此能夠用static型對象來存取一些公用的處理模塊,好比類型轉換、變量驗證等工做。因此要根據具體狀況而定。
還有一點須要注意:若是在頁面中多個過程要共享一個對象或變量,咱們在頁面類的開始部分定義一個頁面級的全局變量是不行的,static原本能夠,但上面說了這種類型的變量不安全,因此這時就能夠用ViewState。
好了,這下咱們能夠放心的暫存某些變量或對象了。
但在隨後的實踐中我發現,在頁面中仍是儘可能少用ViewState變量,由於ViewState變量在客戶端其實是用<input type="hidden" value="ADFAIB3P234P-AFAFAF......"/>保存的一個對象,這樣若是要保存的是個對象,甚至是個很複雜的對象(如DataTable),這樣以來就會增長網絡傳輸的負擔。