Interesting Databinding Behavior

Earlier today, while I was trying to bind a collection to a drop down list, I got the following exception:

    ‘DropDownList1’ has a SelectedValue which is invalid because it does not exist in the list of items.

After inspecting my code, it turned out that the culprit was a rather benign line of code. Since this exception generated is so obscure, I am going to show you the code in its simplest form that would cause this exception so that you can solve similar problems easier.

Suppose I have a drop down list in my aspx page that is bound to a DataTable (the DataSource is not important in the scenario when the exception occurs, it can be an object data source as well, to illustrate the point, I will use a DataTable):

<asp:DropDownList ID="DropDownList1" runat="server" DataSource=‘<%#GetData() %>’ DataTextField="Value" DataValueField="Index" />

Where the data is populated through method GetData()

        protected DataTable GetData()
        {
            DataTable dt = new DataTable();
            DataColumn dc1 = new DataColumn("Index");
            DataColumn dc2 = new DataColumn("Value");
            dt.Columns.Add(dc1);
            dt.Columns.Add(dc2);
 
            DataRow r1 = dt.NewRow();
            r1["Index"] = 0;
            r1["Value"] = "Test1";
            dt.Rows.Add(r1);
 
            DataRow r2 = dt.NewRow();
            r2["Index"] = 1;
            r2["Value"] = "Test2";
            dt.Rows.Add(r2);
 
            return dt;
        }

In the Page_Load method we can bind the DropDownList as follows:

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                DropDownList1.DataBind();
            }
        }

Indeed, this is what we have expected. The problem comes when you try to assign the displayed text to the DropDownList. To illustrate, the following code will cause the exception mentioned earlier:

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                DropDownList1.Text = "This assignment will cause exception";
                DropDownList1.DataBind();
            }
        }

If the text is assigned after the DropDownList is bound however, the code will execute just fine but the assignment will have no effect of course.

Interesting enough, if the above code is placed within a try..catch block, the DataBinding will work just fine even though an exception had been thrown!

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                try
                {
                    DropDownList1.Text = "This assignment will cause exception";
                    DropDownList1.DataBind();
                }
                catch (Exception ex)
                {
                    Response.Write(ex.Message);
                }
            }
        }
Be Sociable, Share!

Leave a Reply