1. 程式人生 > >未能載入檢視狀態(Failed to load ViewState),解決之道

未能載入檢視狀態(Failed to load ViewState),解決之道

在動態載入頁面(使用者控制元件)的時候,我的專案是利用atlas的UpdatePanel載入使用者空間到PlaceHolder中,很容易出現這個錯誤:

Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request. For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Web.HttpException: Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request. For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request. 

 

這個錯誤的原理如下:

在頁面回傳,重新生成時,會自動裝入回傳前的檢視狀態。結合自己的實驗,瞭解的這個過程大致如下:

Init事件 -> ViewState載入 -> Load事件 -> 其它頁面事件(如回傳前的按鈕點選)-> PreRender事件

使用者控制元件動態載入程式碼通常都位於Load事件中(比如我的BindData),或者位於atals的Triger空間EventHandler中,此時整個頁面的ViewState已經載入,就又通過一個有人稱做Catch-up的機制再向PlaceHolder中新載入的控制元件追加其ViewState,而這個ViewState為回傳前在相應位置的控制元件的ViewState。所以如若新的控制元件與舊的型別控制元件不同的話,將出現前述錯誤。

這個錯誤解決起來也很簡單:

在載入新的空間之前,先載入一下原來的控制元件,然後把PlaceHolder Clear掉,然後載入新的控制元件,至於如何儲存原來的控制元件資訊,當然也是使用一個ViewState Property, 比如我的程式碼中的ControlType了!

protectedstring ControlType
        
{
            
get
            
{
                
if (ViewState["ControlType"!=null)
                
{
                    
return ViewState["ControlType"].ToString();
                }

                
return"";
            }

            
set
            
{
                ViewState[
"ControlType"= value;
            }

        }



      ...........................
        
protectedvoid Menu1_MenuItemClick(object sender, MenuEventArgs e)
        
{
            
if (!e.Item.Value.Equals(ControlType))
            
{
                phContainer.Controls.Add(Page.LoadControl(ControlType));  
//這個和前面在BindData裡給ControlType賦值一起是為了防止錯誤"Faild to load view state..."

                phContainer.Controls.Clear();
                ControlType 
= e.Item.Value;
                phContainer.Controls.Add(Page.LoadControl(ControlType));
            }


        }

如下兩個地址可能包含一些有用的資訊: