locked
Asp.net Ajax gets “Failed to load viewstate” problem RRS feed

  • Question

  • I have a data grid custom control called SmartDG. In the SmartDG class, all columns are dynamically built using TemplateColumn class. Here is the example showing how to build a drop down list column:

     

    1. Build a class called DropDownListItem – creating a DropDownList object by using the InstantiateIn method:

     

    Public Class DropDownListItem Implements System.Web.UI.ITemplate

     

    The object of DropDownList is assigned with unique ID when it is created, to avoid the ViewState issue.

     

    2. Build a class called LabelItem – creating a Label object by using the InstantiateIn method:

     

    Public Class LabelItem Implements System.Web.UI.ITemplate

     

    The object of Label is assigned with unique ID when it is created, to avoid the ViewState issue.

     

    3. Build the SmartDG class which is a custom control:

     

    Public Class SmartDG Inherits System.Web.UI.WebControls.WebControl Implements INamingContainer

     

    Notice that all columns/child controls in SmartDG are initiated in the method OnInit to avoid ViewState issue.

     

    4. In the SmartDG class, these code are used to create a drop down list column for the grid. I just make the main statements:

     

    Dim lb As LabelItem = New LabelItem

                   

    Dim ddl As DropDownListItem = New DropDownListItem

    ddl.Autopostback = True

     

    Dim col1 As TemplateColumn = New TemplateColumn

    With col1

              .HeaderText = “Dose”

              .ItemTemplate = lb

              .EditItemTemplate = ddl

    End With

     

    Because of ItemTemplate and EditItemTemplate, when you click “Edit” button on the grid, you get a drop down list (i.e., ddl object) on the cell. When you first time load SmartDG, or when you click the “Cancel” button on the grid, you get a text label (i.e., the lb object) on the cell. Why do I mention these? It is because they may be the cause of producing “failed to load view state” problem in the Ajax application (see the Approach 2 below).

     

    5. Finally, add EditCommandColumn to SmartDG:

     

    Dim editCol As EditCommandColumn = New EditCommandColumn

            With editCol

                .ButtonType = ButtonColumnType.LinkButton

                .ItemStyle.ForeColor = Color.DarkBlue

                .EditText = "Edit"

                .UpdateText = "Update"

                .CancelText = "Cancel"

                .CausesValidation = False

            End With

     

    The steps described above is to indicate how to make columns for the class SmartDG.  Now, I have two approaches:

     

    I. Approach 1 – Non Ajax application: Make a web page non-ajax.aspx file. SmartDG object is dynamically created in the method OnInit. Whenever postback occurs from SmartDG (e.g., postback after selecting an item on the drop down list, or postback after clicking the Edit button on the grid, or postback after clicking the Update button on the grid, etc), SmartDG is rebuilt by the method OnInit on the code-behind file. So far so good. Everything works fine. I can choose an item from the drop down list and the drop down list postback cause no problem. I can click “Edit”, “Update”, or “Cancel” button on the grid without problems.

     

    II. Approach 2 – Ajax application: Every code is as same as above, except ajax code is added. Ajax components are: ScriptManager, UpdatePanel, and TabPanel (derived from the Ajax toolkit). The purpose is to build up a bar with different tabs. When clicking different tab, SmartDG object is created or re-created so that one can see different data grid content. SmartDG object is contained inside the TabPanel object. Whenever a postback occurs, TabPanel and its child SmartDG are rebuilt. Now, so far so good. When I click different tab, different content is shown. Next, I click “Edit” button on the grid, the drop down list works fine to show an item list and an item is selected. I then choose another item on the list, a postback occurs because the drop down list object’s AutoPostBack=true (see point 4 above). Oops! An error pops up:

     

    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.

     

    My guessing is this: Before clicking “Edit”, the column is displayed as text, it is because the column uses an ItemTemplate, which is a Label object(see point 4). After clicking “Edit” (which causes a postback), the column uses EditItemTemplate, which is a DropDownList object (see point 4).  The ViewState at this stage may store Label, but not DropDownList. Up to now, the drop down works fine - it shows a list and an item is selected. However, when I choose another item on the drop down and bring a new postback, the error is produced. The ViewState being loaded may be the DropDownList, but the saved ViewState during the previous request may be the Label. These two do not match and therefore, the program crashes. It is so strange. The same class SmartDG works fine in Non-Ajax application, but not in the Ajax application.

     

    May somebody can help me in this complicated ViewState issue.  Thanks.

     

    NSIG
    Tuesday, March 25, 2008 5:21 PM