Веб-формы ASP.NET DropDownList имеет SelectedValue, который является недопустимым, поскольку он не существует в списке элементов - PullRequest
16 голосов
/ 04 мая 2011

Прежде всего, возникли вопросы ( DropDownList имеет SelectedValue, который недопустим, поскольку его нет в списке элементов , DropDownList "имеет SelectedValue, который недопустим, поскольку существует в списке элементов ", asp: DropDownList Ошибка: для DropDownList1 задано значение SelectedValue, которое недопустимо, так как его нет в списке элементов ) по этому поводу, и есть предложенные обходные пути, но мой вопрос действительно, почему это происходит. Более того, я не удовлетворен предлагаемыми обходными путями и считаю их довольно некрасивыми.

Итак, есть страница с выпадающим списком и кнопкой:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm2.aspx.cs" Inherits="TestWebApplication.WebForm2" ViewStateMode="Disabled" %>

<html lang="en" >
<body>
    <form id="form1" runat="server">
    <div>
        <asp:DropDownList ID="ddlTest" runat="server">
        </asp:DropDownList>
        <asp:Button Text="Test" ID="btnTest" runat="server" onclick="btnTest_Click" />
    </div>
    </form>
</body>
</html>

Я связываю ddlTest с некоторыми элементами в Page_Init, а затем в btnTest_Click, я связываюсь снова:

using System;

namespace TestWebApplication
{
    public partial class WebForm2 : System.Web.UI.Page
    {
        protected void Page_Init(object sender, EventArgs e)
        {
            //SelectedIndex is -1, SelectedValue is "", SelectedItem is null
            ddlTest.DataSource = new[] { 1, 2, 3 };
            ddlTest.DataBind();
            ddlTest.SelectedValue = "3";
        }

        protected void btnTest_Click(object sender, EventArgs e)
        {
            //SelectedIndex is 2, SelectedValue is "3", SelectedItem is {3}
            ddlTest.ClearSelection();
            //SelectedIndex is 0, SelectedValue is "1", SelectedItem is {1}
            ddlTest.SelectedIndex = -1; //Nothing changes including SelectedIndex
            ddlTest.SelectedValue = ""; //Nothing changes including SelectedValue
            ddlTest.Items.Clear();
            //SelectedIndex is -1, SelectedValue is "", SelectedItem is null
            ddlTest.DataSource = null; //Nothing changes except for the DataSource property
            ddlTest.DataSource = new[] { 1, 2 };
            ddlTest.DataBind();//Exception!
            //'ddlTest' has a SelectedValue which is invalid because it does not exist in the list of items.
            //Parameter name: value
        }
    }
}

Почему я получаю исключение. Я пробовал разные версии этих и ни одна из них не работает. Я пытался использовать только ClearSelection, но все равно получил то же исключение. Это ошибка в элементе управления или что-то я скучаю. Являются ли уродливые обходные пути от других вопросов единственным решением?

Примечание - ошибка воспроизводима, даже если кнопка удалена и весь код перемещен в один обработчик события. Просто связать один раз, установить выбранное значение и связать снова.

Ответы [ 6 ]

32 голосов
/ 11 сентября 2011

Я отправил сообщение об ошибке в Connect.Это было решено как "Не исправлю", что, на мой взгляд, означает, что это на самом деле ошибка.Был предоставлен обходной путь:

ddlTest.Items.Clear();
ddlTest.SelectedValue = null;

https://connect.microsoft.com/VisualStudio/feedback/details/666808/asp-net-dropdownlist-selectedvalue-is-persisted-which-results-in-exception-if-the-control-is-databound-second-time

Я считаю это ответом.

3 голосов
/ 05 октября 2011

У меня была похожая проблема, и я исправил ее, добавив метод DataBinding.

protected void myDDL_DataBinding(object sender, EventArgs e)
{
    if (myDDL.SelectedIndex != -1)
    {
        myDDL.SelectedIndex = 0;
    }
}

На странице дизайна ...

<asp:DropDownList ID="myDDL" runat="server" 
    AutoPostBack="true" OnDataBinding="myDDL_DataBinding"
    OnSelectedIndexChanged="myDDL_SelectedIndexChanged">
</asp:DropDownList>
3 голосов
/ 07 мая 2011

Почему я получаю исключение.

После вызова Page_Init () ddlTest был привязан к 3 элементам: «1», «2» и «3». Затем вы устанавливаете SelectedValue на «3» и манипулируете всеми видами вещей, связанных с элементом управления DropDownList. Но элемент управления по-прежнему привязан к предыдущему списку - вы больше не вызывали .DataBind (), даже если вы изменили свойства DropDownList. Исключение возникает из-за того, что элемент управления по-прежнему привязан к {1, 2, 3}, он привязан к предыдущему .SelectedValue, и вы только что попытались .DataBind () передать его в список, который не содержит «3».

2 голосов
/ 04 мая 2011

1) Как написано, ваш пример фактически генерирует исключение для ddlTest.SelectedValue = "";, поскольку в коллекции нет элемента с Value, равным "". Я думаю, что этого следовало ожидать при любых обстоятельствах.

2) Я получаю исключение каждый раз, когда пытаюсь установить SelectedValue или SelectedIndex для DDL на что-то, что БУДЕТ недействительным к моменту, когда DDL будет обработан. Но исключение не происходит до тех пор, пока коллекция DropDownList.Items не изменится, например, с DropDownList.Databind(). Первое, что я сделал, это изменил Page_Init:

protected void Page_Init(object sender, EventArgs e)
{
    //SelectedIndex is -1, SelectedValue is "", SelectedItem is null
    if (!IsPostBack)
    {
        ddlTest.DataSource = new[] { 1, 2, 3 };
        ddlTest.DataBind();
        ddlTest.SelectedValue = "3";
    }
}

Теперь то, что становится интересным, это первый пример, который выдает исключение, а второй - нет. Они оба устанавливают SelectedValue, который действителен в то время, но значение в первом примере («3») не будет действительным ко времени рендеринга страницы:

protected void btnTest_Click(object sender, EventArgs e)
{
    //SelectedIndex is 2, SelectedValue is "3", SelectedItem is {3}
    ddlTest.SelectedValue = "3"; 
    //SelectedIndex is 2, SelectedValue is "3", SelectedItem is {3}
    ddlTest.ClearSelection();
    //SelectedIndex is 0, SelectedValue is "1", SelectedItem is {1}
    ddlTest.Items.Clear();
    //SelectedIndex is -1, SelectedValue is "", SelectedItem is null
    ddlTest.DataSource = null;
    ddlTest.DataSource = new[] { 1, 2 };
    ddlTest.DataBind(); //Exception!
    //'ddlTest' has a SelectedValue which is invalid because it does not exist in the list of items.
    //Parameter name: value
}

protected void btnTest_Click(object sender, EventArgs e)
{
    //SelectedIndex is 2, SelectedValue is "3", SelectedItem is {3} (from viewstate)
    ddlTest.SelectedValue = "2"; 
    //SelectedIndex is 1, SelectedValue is "2", SelectedItem is {3}
    ddlTest.ClearSelection();
    //SelectedIndex is 0, SelectedValue is "1", SelectedItem is {1}
    ddlTest.Items.Clear();
    //SelectedIndex is -1, SelectedValue is "", SelectedItem is null
    ddlTest.DataSource = null;
    ddlTest.DataSource = new[] { 1, 2 };
    ddlTest.DataBind(); //No Exception...
}

Итак, какой вывод мы можем из этого сделать? Что ж, похоже, проблема связана с установкой свойства DDL SelectedIndex или SelectedValue до того, как содержимое DDL может быть изменено в одном и том же цикле страницы. Если ранее установленное значение все еще доступно в новом содержимом DropDownList.Items, вы в деле. Но если его там нет, вы получите исключение.

Полагаю, это как-то связано с безопасностью потоков, но я не специалист по этому вопросу, так что, надеюсь, кто-то может прокомментировать.

0 голосов
/ 25 июля 2012

В моем случае у меня было DropdownList в templatedfield из gridview.Теперь datasource сетки имеет employeeid предмет.У меня есть это в сохраненной процедуре, isnull(employeeid,0) для источника данных, и я предполагаю, что DropdownList не имеет значения 0 для своих элементов;поэтому я изменил это на isnull (employeeid, 1), потому что первый элемент в DropdownList имеет employeeid =1, и это решило проблему

0 голосов
/ 03 февраля 2012

Поскольку нет источника данных при перезагрузке вашей страницы (произошла обратная передача), вы должны добавить элемент управления SqlDataSource в свой файл .aspx даже при перезагрузке страницы, чтобы распознать DataSource DropDownList. Затем вы можете использовать InsertCommand, UpdateCommand, DeleteCommand и SelecCommand для получения вашей БД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...