Asp.net中static變數和viewstate的使用方法(謹慎)

來源:互聯網
上載者:User

在.Net平台下進行CS軟體開發時,我們經常遇到以後還要用到某些變數上次修改後的值,為了簡單起見,很多人都習慣用static來定義這些變數,我也是。這樣非常方便,下一次調用某個函數時該變數仍然儲存的是處理過的值,直接拿來用就可以了。

現在轉入了BS軟體開發,我們很自然地會沿用這種習慣。如在頁面中統計某個按鈕被按下的次數,先在類中OnClick事件的處理過程前定義一static變數times,則每次調用該按鈕的OnClick事件時,令times增1即可,非常方便:
[C#]:

複製代碼 代碼如下:...
static int times=0;
...
private void Button1_Click(object sender,EventArgs e)
{
times++;
Label1.Text=times.ToString();
}

在我們慶幸如此方便之餘,就未曾意識到我們已經埋下了一棵難以察覺的定時炸彈。為什麼哪?
這還要從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的用法很簡單,如下所示
1、儲存變數到ViewState中:
ViewState["times"]=times;//存放普通變數times
ViewState["Orders"]=dtOrders;//存放DataTable型對象dtOrders
2、讀出ViewState中的值:
times=(int)ViewState["times"];
dtOrders=(DataTable)ViewState["Orders"];
看見了吧?就如此簡單!有的朋友會問讀出變數的值時為什麼要進行強制類型轉換?這是因為當變數(不管是int型的普通變數times,還是DataTable型的對象dtOrders)被存放到ViewState中後,ViewState可不管你是普通變數還是對象,統統按Object來對待。所以當我們取出存放在ViewState中的東西時,一定要轉換成相應的類型,否則就會報錯。而這一操作不用在用ViewState儲存變數時進行,系統會自動轉換。(注意ViewState括弧中的字串只是為了標識不同變數的索引,用不著非要和變數同名)所以上面計數器的代碼應該這樣寫才好: 複製代碼 代碼如下:...
ViewState["times"]=0;
...
private void Button1_Click(object sender,EventArgs e)
{
int times=(int)ViewState["times"];
times++;
ViewState["times"]=times;
Label1.Text=times.ToString();
}

一般情況向下,將要儲存到ViewState中的對象(或變數)用屬性的形式來實現會更方便。如對於上述的計數器times,可以這樣處理: 複製代碼 代碼如下:...
private int times
{
get
{
return (int)ViewState["times"];
}
set
{
ViewState["times"]=value;
}
}
...
private void Button1_Click(object sender,EventArgs e)
{
times++;
Label1.Text=times.ToString();
}
...

在這裡times將當作私人屬性來操作,是不是非常方便?
那是不是說static型變數就沒用了哪?當然不是!在C#中用static聲明的類不用執行個體化直接使用。正是由於所有使用者共用伺服器端的同一個static變數,所以可以用static型對象來存取一些公用的處理模組,比如類型轉換、變數驗證等工作。所以要根據具體情況而定。

還有一點需要注意:如果在頁面中多個過程要共用一個對象或變數,我們在頁面類的開始部分定義一個頁面級的全域變數是不行的,static本來可以,但上面說了這種類型的變數不安全,所以這時就可以用ViewState。

好了,這下我們可以放心的暫存某些變數或對象了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.