理解Asp.net中的View state

來源:互聯網
上載者:User
asp.net

什麼是ViewState?
對於ViewState,我們有許多的誤解。Viewstate不儲存控制項,而是去儲存form中對應ID控制項的值,特別是那些由於他們沒有和form一起post 而在頁面回傳時會丟失的控制項的值。viewstate一般不要用來儲存session或在頁面間傳輸資料。在頁面回傳後,viewstate不能用來動態地建立頁面的控制項。他在頁面回傳之後不回複控制項的值。甚至一個控制項的viewstate被禁止了,在頁面回傳後,控制項的值仍然不會丟失,比如textbox,dropdownlist控制項。那什麼是viewstate呢?viewstate儲存最後一次在伺服器上處理的頁面狀態。他不能儲存那些被動態改變的控制項的值。

viewstate是如何工作的?
所有的伺服器端控制項都有一個ViewState屬性。如果他是enable的,這個控制項的viewstate就起作用了。那viewstate是在哪裡,是如何儲存的呢?當一個頁面第一次載入,所有的控制項被序列化到viewstate,儲存在一個叫_ViewState的隱藏form欄位裡。這個隱藏欄位對應伺服器端的ViewState對象。頁面的ViewState使用System.Web.UI.StateBagObject Storage Service索引值對。當一個回傳發生,頁面還原序列化ViewState然後恢複所有的控制項。頁面中儲存控制項的ViewState以base 64 編碼格式儲存成name - value。當一個頁面重新載入,會調用兩個和ViewState相關的方法, LoadViewState 和SaveViewState。下面是我的一個頁面中的_ViewState隱藏欄位。

<input type="hidden" name="__VIEWSTATE" value="dNrATo45Tm5QzQ7Oz8AblWpxPjE9MMl0Aq765QnCmP2TQ==" />
啟用和禁止ViewState
在預設情況下,所有伺服器控制項的viewstate開啟狀態,通過以及幾種途徑來禁止。
1.頁面層級
2.控制項層級
3.應用程式層級
4.機器層級
頁面層級禁止的方法是在頁面的開始寫入

<%@ Page EnableViewState ="False" %>
or
<%@ Page EnableViewState ="True" %>
控制項層級是

<asp:TextBox id="txtCode" runat="server” EnableViewState="false" />
or
<asp:TextBox id="txtCode" runat="server" EnableViewState="true" />
程式層級是在web.config中

<pages enableViewState="false" />
or
<pages enableViewState="true" />
機器層級是在machine.config中

<pages enableViewState="true" enableViewStateMac="true" ... />
or
<pages enableViewState="false" ... />
在viewstate中儲存和取出值
viewstate能處理以下的類型
基本類型,基本類型數組,ArrayList 和Hashtable,任何可以序列化的對象。

以下代碼是將ArrayList存到viewstate中並取出

ArrayList obj = new ArrayList();
//Some code
ViewState["ViewStateObject"] = obj;
   obj = ViewState["ViewStateObject"];
效能問題
為了更好的頁面呈現效能,viewstate應該儘可能的小。要記住Viewstate中的資料會佔用很多的網路頻寬。因此我們要謹慎的利用viewstate。如果頁面和控制項不需要回傳,那麼就要禁止viewstate屬性。通常在aspx頁面之外儲存Viewstate會取得更好的效能表現。為了達到這個目的,我們可以使用SavePageStateToPersistenceMedium 和LoadPageStateFromPersistenceMedium 這兩個方法。在web.config或machine.config設定來禁止某個程式的所有頁面或全部程式頁面的viewstate。

注意只有控制項包含在<form runat=server>裡才能儲存viewstate。然而即使頁面所有的viewstate被禁止,頁面仍然在viewstate中儲存20位元組的資料,用來在回傳時為相應的控制項分配viewstate中的資料。所以當頁面完全沒有回傳,移去runat="server"能減少20位元組的資料。如果有很多這樣的頁面,20位元組的節省也能在一定程度上減少頻寬。viewstate應該在必要的時候使用。在DataGrid和DataRepeater這樣的控制項中要避免使用viewstate,因為這些控制項的viewstate佔用資料相當大。

下面我提供一個簡單的用於計算頁面viewstate大小的方法。建立一個MasterPageBase 類,然後其他所有的頁面都要繼承他。

public class MasterPageBase: System.Web.UI.Page
...{
  protected override void OnPreRender(EventArgs e)
  ...{
    object viewStateObject = HttpContext.Current.Request["__VIEWSTATE"];
    if (viewStateObject == null)
      HttpContext.Current.Trace.Warn("The ViewState Size is:", "0");
    else
      HttpContext.Current.Trace.Warn("The ViewState Size is:",
        HttpContext.Current.Request["__VIEWSTATE"].Length.ToString());
    base.OnPreRender(e);
  }
}
安全問題
可以採取兩個措施來避免viewstate被仿冒
使用EnableViewStateMac屬性
給 ViewState中的內容加密
EnableViewStateMac會進行一個機器授權驗證(MAC),這應在頁面層級或程式層級使用。當設定時,這個屬性會在viewstate呈現之前附加一個viewstate的hash值。當回傳發生時,hash值會被重新計算和核對。如果他們不匹配,頁面會拒絕顯示,這樣就確保了viewstate沒有被纂改。

在machine.config中設定對viewstate內容的加密

<machineKey validation="3Des" /> or <machineKey validation="SHA1"/>
viewstate容易出錯的地方
當將一個頁面的控制項傳輸到另外一個頁面(第二個頁面)時,通常會出現錯誤。解決方案是在第二個頁面中將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.