The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

釐清 ViewState 與動態加入的控制項可能發生的錯誤

今天在這裡看了一篇關於 ViewState 的文章,他將 ViewState 的運作寫的清清楚楚,撰寫 ASP.NET 的程式設計師一定不能錯過這篇文章。

我摘要一下他這篇文章說明的結論:

  1. ASP.NET 試著透過 ViewState 來紀錄與回存控制項(Control)的狀態,但 ViewState 只有紀錄 Control 出現的順序,當動態加入的 Control 順序不一樣的時候,ViewState 的內容就會變得無意義,且有可能發生 Exception 導致程式中斷。通常的錯誤訊息是:

    無法載入 Viewstate。Viewstate 所要載入的控制項樹狀結構必須符合在先前要求期間用來儲存 Viewstate 的控制項樹狀結構。例如,以動態方式加入控制項時,在回傳期間加入的控制項必須符合在初始要求期間所加入控制項的型別和位置

    例如說以下這段程式碼,當頁面第一次顯示時會出現 Button 並顯示 Click me 字樣,但 PostBack 之後,會變成 Label 控制項,且 Label 控制項的 Text 屬性也竟然是 Click me !但我們在程式中並沒有指定 Label 的 Text 屬性!!

    [code:c#]
    public partial class _Default : Page
    {
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (!IsPostBack)
            {
                Button btnClickMe = new Button();
                form1.Controls.Add(btnClickMe);
                btnClickMe.Text = "Click me";
                btnClickMe.CommandName = "XXX";
            }
            else
            {
                Label label = new Label();
                form1.Controls.Add(label);
            }
        }
    }
    [/code]

  2. 當 ViewState 回存到「不同型別」的控制項時,就有可能發生以下錯誤:

    1. 當執行時期執行到 Control.LoadViewState() 方法時,發生 InvalidCastException 或存取控制項的屬性時發生 Exception
    2. 當控制項的屬性收到非預期的資料(例如:回復不同型別的資料)
    3. 控制項的 ViewState 會越來越多,但卻不知道這些資料是從哪裡來的

    其中第 2, 3 點是最難發現與最難除錯的地方。

這篇文章英文還可以的人可以看完整版,可以學到更完整的知識。
網址在:http://geekswithblogs.net/FrostRed/archive/2007/02/17/106547.aspx

我個人是認為如果你使用很多動態加入的控制項的話,建議你還是關閉這些控制項的 ViewState 減少一些潛在的麻煩,如果真的要用那就要多費些心思規劃好控制項的出現順序,保持其一致性!