ASP.Net MVC SelectList не выбирает правильный элемент

Меня попросили посмотреть на ошибку в каком-то коде ASP.Net MVC, и у меня возникла (для меня) очень странная проблема с SelectList.

Код контроллера для генерации элементов (метод возврата SelectList, всего их 5). Затем каждый SelectList сохраняется в коллекции ViewData.

List<SelectListItem> items = new List<SelectListItem>();
string yesText = "Yes";
string noText = "No";
if (ci.LCID.Equals((int)LanguageCodes.FRANCE))
{
    yesText = "Oui";
    noText = "Non";
}

SelectListItem yesItem = new SelectListItem();
yesItem.Text = yesText;
yesItem.Value = ((int)MarketingBy.Yes).ToString();
yesItem.Selected = selectedValue != null && selectedValue.Equals(int.Parse(yesItem.Value));

SelectListItem noItem = new SelectListItem();
noItem.Text = noText;
noItem.Value = ((int)MarketingBy.No).ToString();
noItem.Selected = selectedValue != null && selectedValue.Equals(int.Parse(noItem.Value));

items.Add(yesItem);
items.Add(noItem);

return new SelectList(items, "Value", "Text", yesItem.Selected ? yesItem.Value : noItem.Value);

Быстрое наблюдение в момент создания показывает, что все в порядке:  Выбрать созданный список

В момент рендеринга представления значения все еще выглядят нормально. Однако при загрузке представления всегда выбирается первый элемент в списке. Сгенерированный HTML:

<tr>
<td>Fax</td>
<td>
    <select id="MarketingByFax" name="MarketingByFax">
        <option value="134300002">Yes</option>
        <option value="134300001">No</option>
    </select>
</td>
</tr>

(Другие значения опущены для ясности).

Любые идеи? Или пути к исследованиям? Автор непреклонен в том, что это работало «до прошлой недели» (я не имею ни малейшего представления).

Изменить: код для представления -

<td><%: Html.DropDownList("MarketingByFax", (SelectList)ViewData["MarketingByFaxList"])%></td>

person glosrob    schedule 15.06.2011    source источник
comment
Можете ли вы добавить код из вашего представления? Вы используете Html.DropDownList или Html.DropDownListFor?   -  person FlyingDeveloper    schedule 15.06.2011
comment
Html.DropDownList используется (теперь тоже добавлен в вопрос)   -  person glosrob    schedule 15.06.2011


Ответы (2)


Этот код выглядит просто ужасно во всех мыслимых аспектах (ИМХО, конечно). Я понятия не имею, почему это не работает, и не хочу знать. Все, что я могу сделать, это посоветовать вам, как его улучшить (так что вы можете прекратить читать этот пост, если ищете решение, почему ваш код не работает, поскольку я понятия не имею).

Итак, первым улучшением было бы избавиться от любого ViewData и ввести модель представления:

public class MyViewModel
{
    public string SelectedValue { get; set; }
    public IEnumerable<SelectListItem> Items { get; set; }
}

тогда у меня будет действие контроллера, которое заполнит эту модель представления:

public ActionResult Index()
{
    var model = new MyViewModel
    {
        // I want to preselect the second value
        SelectedValue = "No",
        Items = new[]
        {
            new SelectListItem { Value = "Yes", Text = "yeap !" },
            new SelectListItem { Value = "No", Text = "nope !" },
        }
    };
    return View(model);
}

и в моем строго типизированном представлении я бы просто привязал помощника к модели представления:

<%= Html.DropDownListFor(
    x => x.SelectedValue,
    new SelectList(Model.Items, "Value", "Text")
) %>

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

Видишь, как это просто? Больше никаких уродливых приведений с ViewData, больше нет необходимости определять какие-либо списки и указывать некоторые сложные условия, ...

Реплика: еще раз, это всего лишь мои 2 ¢, можете продолжить бой с ViewData, если хотите.

person Darin Dimitrov    schedule 15.06.2011
comment
Приносим извинения за поздний ответ. Я согласен с большей частью того, что вы изложили выше, особенно с частями ViewModel / ViewData. Первоначально это был не мой код, и, к сожалению, я не мог позволить себе перерыв в моем проекте, который потребовался бы для его полной переписывания (на рассматриваемой странице было гораздо больше того, что указано выше) ... так что это технически правильный ответ, но не то, что было использовано в данном конкретном случае. - person glosrob; 17.06.2011
comment
@Darin Твои ответы волшебны. они всегда появляются в тот момент, когда я собираюсь задать аналогичный вопрос, немного связанный с моим вопросом. и это решает мою проблему - person Eon; 12.12.2016

можешь попробовать

<%: Html.DropDownList("MarketingByFax", (IEnumerable<SelectListItem>)ViewData["MarketingByFaxList"])%>

dropdwon имеет перегрузку, которая принимает перечисление объектов типа Selectlist и автоматически устанавливает значение списка в зависимости от свойства Selected элемента selectListItems в списке. для этого вам нужно установить

ViewData["MarketingByFaxList"] = items;//where item is IEnumerable<SelectListItem> or List<SelectListItem> as you used in your code
person Muhammad Adeel Zahid    schedule 15.06.2011