SelectedValue fails when returning to DropDownList

I recently discovered a weird behavior inside an ASP.NET DropDownList that I hope someone can explain.

Basically the problem I am facing is data binding before postback, and then setting SelectedValue to a value that does not exist in the data list, that the call simply has no effect. However, upon postback, the same call will end with ArgumentOutOfRangeException()

'cmbCountry' has a SelectedValue value, which is not valid because it does not exist in the list of items. Parameter Name: Value

I am using the following code.

 protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { cmbCountry.DataSource = GetCountries(); cmbCountry.DataBind(); cmbCountry.SelectedValue = ""; //No effect } else { cmbCountry.SelectedValue = ""; //ArgumentOutOfRangeException is thrown } } protected List<Country> GetCountries() { List<Country> result = new List<Country>(); result.Add(new Country() { ID = Guid.NewGuid(), Description = "Test" }); result.Add(new Country() { ID = Guid.NewGuid(), Description = "Test1" }); result.Add(new Country() { ID = Guid.NewGuid(), Description = "Test2" }); result.Add(new Country() { ID = Guid.NewGuid(), Description = "Test3" }); return result; } public class Country { public Country() { } public Guid ID { get; set; } public string Description { get; set; } } 

Can someone clarify the reason for this behavior for me and let me know if there are any workarounds?

+6
source share
2 answers

I'm not sure why it was designed this way, but DropDownList only throws this exception in PostBack ... here's the installer code from ILSpy:

 public virtual string SelectedValue { get { ... } set { if (this.Items.Count != 0) { if (value == null || (base.DesignMode && value.Length == 0)) { this.ClearSelection(); return; } ListItem listItem = this.Items.FindByValue(value); /********** Checks IsPostBack here **********/ bool flag = this.Page != null && this.Page.IsPostBack && this._stateLoaded; if (flag && listItem == null) { throw new ArgumentOutOfRangeException("value", SR.GetString("ListControl_SelectionOutOfRange", new object[] { this.ID, "SelectedValue" })); } if (listItem != null) { this.ClearSelection(); listItem.Selected = true; } } this.cachedSelectedValue = value; } } 

You can get around this by setting the SelectedValue to null instead of an empty string.

+2
source

DropDownList > SelectedValue Property > ArgumentOutOfRangeException

The selected value is not in the list of available values ​​and in the view of the state or another state (a postback was performed). See the Remarks Section for more information.

Source: MSDN

DropDownList> SelectedValue Property> Notes

(...) When the selected value is not in the list of available values ​​and a postback is performed, an ArgumentOutOfRangeException is thrown. (...)

Source: MSDN

In addition, I performed the following test:

  • In !IsPostBack , a list with 4 items has !IsPostBack added as a data source, identifiers 1 ~ 4
  • Set SelectedValue = 5
  • New item added using combo.Items.Add(new ListItem()...) with id 5

I expected to see ID 5 as the current selected item in combo, but this did not happen.

After all, this looks like design behavior. I did not find any more information, so my following thoughts: it seems that after arbitrary installation of a control data source, the developer can freely choose a nonexistent element that simply will not have any effect. However, after linking the viewstate to reverse processing, the checklist is checked (or something like that), so it needs to be handled accordingly.

+2
source

Source: https://habr.com/ru/post/922183/


All Articles