A Bug in DropDownList

來源:互聯網
上載者:User

A DropDownList Bug

I found there was a bug in System.Web.UI.WebControls.DropDownList recently.
When I created items for a DropDownList control using DropDownList.DataBind method, an exception was always thrown. The error message looked like:

'DropDownList_Option' has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value

At first, I thought maybe I should clear the selection before invoking DataBind method because the word "SelectedValue" was mentioned in the error.
I then began to try the following methods:

  • DropDownList_Option.ClearSelection();
  • DropDownList_Option.SelectedIndex = -1;

But unfortunatelly none of the them worked. The exception was still thrown. I got confused at that time. Because abviously we had nothing selected.
With "Reflector"'s help, I finally found the reason. It seemed it was a bug there which I would introduce the details below. To bypass the bug,
you can just simply try:

DropDownList_Option.SelectedValue = null;

It was so strange, wasn't it?

How to reproduce the bug

It's very simple to reproduce the bug. Just use the code segment below:

// MyDataItem class definition//public class MyDataItem{  private string _text;  private string _value;  public MyDataItem(string text, string value)  {    _text = text;    _value = value;  }  public string Text  {    get { return _text; }  }  public string Value  {    get { return _value; }  }}// Reproduce the DropDownList bug here// e.g. we have a DropDownList variable called DropDownList_Option for now.//List items1 = new List();items1.Add(new MyDataItem("Text1", "Value1"));items1.Add(new MyDataItem("Text2", "Value2"));items1.Add(new MyDataItem("Text3", "Value3"));DropDownList_Option.DataTextField = "Text";DropDownList_Option.DataValueField = "Value";DropDownList_Option.DataSource = items1;DropDownList_Option.DataBind();// Makes the first item selected.// Please note if we use "DropDownList_Option.SelectedIndex = 0;" here, there will be no exceptions.// DropDownList_Option.SelectedValue = "Value1";List items2 = new List();items2.Add(new MyDataItem("2 - Text1", "2 - Value1"));items2.Add(new MyDataItem("2 - Text2", "2 - Value2"));items2.Add(new MyDataItem("2 - Text3", "2 - Value3"));DropDownList_Option.SelectedIndex = -1;DropDownList_Option.ClearSelection();DropDownList_Option.DataSource = items2;DropDownList_Option.DataBind();  // An exception will be thrown here!

Why does the bug appear?

To realise why the bug always appears, we have to have a deep look into .Net Framework source code.
We are so lucky that we have Reflector. It provides us the valuable source code. Thanks Reflector!

  • The exception is thrown in ListControl.PerformDataBinding method:

    //  Generated code by Reflectorif(dataSource != null){  // Creates ListItem(s) here  // ....}if (this.cachedSelectedValue != null){  int num = -1;  num = this.Items.FindByValueInternal(this.cachedSelectedValue, true);  if (-1 == num)  {    throw new ArgumentOutOfRangeException("value", SR.GetString("ListControl_SelectionOutOfRange", new object[] { this.ID, "SelectedValue" }));  }  // ....}    
  • I've simplified the code segment to let us read it a bit easier than before. We can see that a new variable called "cachedSelectedValue" is introduced here.
    If its value is not null, then an exception will probably thown. So we'll concentrate on the following questions for now:

    • Where is "cachedSelectedValue" assigned?
    • Will "cachedSelectedValue" be changed if we invoke "ListControl.ClearSelection", or set values for "ListControl.SelectedValue" and "ListControl.SelectedIndex"?
  • Let's move on. "cachedSelectedValue" is only assigned by "ListControl.SelectedValue"(except ListControl.PerformDataBinding)! Neither "ListControl.ClearSelection" nor "ListControl.SelectedIndex" will change "cachedSelectedValue".
  • So the problem comes. When we're assigning a value to the property "SelectedValue", "cachedSelectedValue" is also assigned with the same value.
    Then we want to clear all the selections. We try to invoke "ClearSelection" method, or assign -1 to the property "SelectedIndex". They all make sense. However,
    they don't clear "cachedSelectedValue" variable at the same time. They make the DropDownList instance go into an inconsistent state. Finally when calling
    DropDownList.DataBind method, we get an exception thrown.

There are also 2 similar variables called "cachedSelectedIndex/cachedSelectedIndices" in ListControl. I'm not sure whether they'll cause exceptions or not.
You can try it if you're interested in it.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.