Хобрук: Ваш путь к мастерству в программировании

DropDownList устанавливает выбранный элемент в asp.net MVC

Я заметил, что мне кажется ошибкой в ​​asp.net MVC, или просто я что-то делаю не так. В настоящее время я использую 1.0, так что, возможно, это будет решено в версии 2.0. Но в любом случае, поехали.

Когда у моей модели представления есть свойство, имя которого совпадает с именем, объявленным идентификатором для раскрывающегося списка, выбранный элемент игнорируется, и в визуализированном html ничего не выбрано. Не уверен, что я сделал что-то не так, но изменение имени идентификатора решает проблему. Я упростил пример, надеюсь, он понятен, в противном случае дайте мне знать.

Вот мое мнение, где заявленный идентификатор совпадает с именем моего списка в модели:

<table border="0" cellpadding="0" cellspacing="0">
   <tr>
      <td>
         <%= Html.DropDownList("IsMultipleServicers", Model.IsMultipleServicers) %>
      </td>
   </tr>
</table>

И обработанный HTML

<table border="0" cellpadding="0" cellspacing="0">
      <tr>
         <td>
             <select id="IsMultipleServicers" name="IsMultipleServicers">
                <option value="false">No</option>
                <option value="true">Yes</option>
             </select>
         </td>
      </tr>
</table>

Теперь внесем небольшое изменение. Я изменю заявленный идентификатор на другой.

Вот мой взгляд:

<table border="0" cellpadding="0" cellspacing="0">
    <tr>
       <td>
          <%= Html.DropDownList("MultipleServicers", Model.IsMultipleServicers) %>
       </td>
    </tr>
</table>

А теперь обработанный HTML:

<table border="0" cellpadding="0" cellspacing="0">
   <tr>
      <td>
         <select id="IsMultipleServicers" name="IsMultipleServicers">
            <option value="false">No</option>
            <option selected="selected" value="true">Yes</option>
         </select>
      </td>
   </tr>
</table>

Обратите внимание, что теперь я получаю выбранный вариант, который будет вторым элементом в списке.

Вот моя ViewModel, чтобы связать все вместе:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MVCProject.Models.ViewModels.Service
{
    public class ServiceViewModel : ViewModel
    {
         public List<SelectListItem> IsMultipleServicers { get; set; }
    }
}

Вот мое действие:

[AcceptVerbs(HttpVerbs.Get)]
public virtual ActionResult Service()
{
   return View(new ServiceViewModel()
   {
      IsMultipleServicers = BuildBooleanSelectList(true)
   };
}

 private List<SelectListItem> BuildBooleanSelectList(bool isTrue)
 {
    List<SelectListItem> list = new List<SelectListItem>();

    if (isTrue)
    {
       list.Add(new SelectListItem() { Selected = false, Text = "No", Value = "false" });
       list.Add(new SelectListItem() { Selected = true, Text = "Yes", Value = "true" });
    }
    else
    {
       list.Add(new SelectListItem() { Selected = true, Text = "No", Value = "false" });
       list.Add(new SelectListItem() { Selected = false, Text = "Yes", Value = "true" });
    }
 return list;
  }

Ответы:


1

Я думаю, проблема в путанице с DropDownList перегрузками:

  1. Html.DropDownList(string name) ищет свойство модели представления name и типа IEnumerable<SelectListItem>. Он будет использовать выбранный элемент (SelectListItem.Selected == true) из списка, если нет одноименного значения сообщения формы.

  2. Html.DropDownList(string name, IEnumerable<SelectListItem> selectList) использует элементы из selectList, но не их выбранные значения. Выбранное можно найти путем разрешения name в модели представления (или данных публикации) и сопоставления его с SelectListItem.Value. Даже если значение не может быть найдено (или равно нулю), оно все равно не будет использовать выбранное значение из списка SelectListItems.

Ваш код использует вторую перегрузку, но указывает несуществующее свойство «значение» («MultipleServicers»).

Чтобы решить вашу проблему, используйте первую перегрузку:

<%= Html.DropDownList("IsMultipleServicers") %>

Или добавьте свойство string MultipleServicers в свою модель представления и заполните его в своем контроллере. Я бы порекомендовал это решение, поскольку оно позволяет решить несколько проблем с начальным отображением, отображением публикации и сопоставлением данных публикации с моделью просмотра / публикации:

public class ServiceViewModel : ViewModel 
{ 
     public string MultipleServicers { get; set; } 
     public List<SelectListItem> IsMultipleServicers { get; set; } 
}

Затем для вашего HTML:

<%= Html.DropDownList(Model.MultipleServicers, Model.IsMultipleServicers) %>

Этот метод также отображается в MVC2:

<%= Html.DropDownListFor(x => x.MultipleServicers, Model.IsMultipleServicers) %>
09.03.2010
  • Хотелось бы, чтобы это было более очевидным ... Но теперь это имеет смысл. Спасибо 14.04.2015
  • я бы порекомендовал вам все это: c-sharpcorner.com/UploadFile/4d9083/ 12.08.2015

  • 2

    Я столкнулся с этой же проблемой при использовании перегрузки Html.DropDownList (имя строки, IEnumerable selectList). Похоже, что у моей модели есть свойство с тем же именем, что и имя раскрывающегося списка. В этом случае MVC предпочел значение свойства моей модели свойству Selected каждой записи в IEnumerable.

    Решением было использовать имя для раскрывающегося списка, не совпадающее с именем свойства. Другим решением было бы написать собственный метод расширения, который игнорирует состояние модели и представления и вместо этого всегда учитывает выбранное свойство.

    09.03.2010
  • Мне приходилось использовать этот подход раньше для быстрых исправлений, но я думаю, что после этого хорошо вернуться и провести рефакторинг ваших моделей представления, чтобы лучше использовать Html.DropDownList, как он был предназначен для использования (насколько это может сбивать с толку) 02.06.2011

  • 3

    Помощник DropDownList извлекает значение по умолчанию из модели. В первом случае значение в модели, соответствующее имени, является SelectList - это не соответствует ни одному из элементов в списке, это список, поэтому значение не выбирается. Во втором примере ваша модель не включает свойство с таким именем, поэтому значение из модели нельзя использовать, и оно по умолчанию соответствует состоянию, указанному в самом списке SelectList. Обычно у меня будет свойство модели для выбранного значения - оно становится значением по умолчанию - и другое свойство, представляющее потенциальные значения для списка.

    09.03.2010
  • Хорошее объяснение происходящего! Сам выбрал вашу практику по умолчанию - кажется, лучший способ сделать вещи явными и упрощает генерацию значений SelectListItem. 05.12.2015
  • Новые материалы

    Не зря же это называют интеллектом
    Стек — C#, Oracle Опыт — 4 года Работа — Разведывательный корпус Мне пора служить Может быть, я немного приукрашиваю себя, но там, где я живу, есть обязательная военная служба на 3..

    LeetCode Проблема 41. Первый пропущенный положительный результат
    LeetCode Проблема 41. Первый пропущенный положительный результат Учитывая несортированный массив целых чисел, найдите наименьшее пропущенное положительное целое число. Пример 1: Input:..

    Расистский и сексистский робот, обученный в Интернете
    Его ИИ основан на предвзятых данных, которые создают предрассудки. Он словно переходит из одного эпизода в другой из серии Черное зеркало , а вместо этого представляет собой хронику..

    Управление состоянием в микрофронтендах
    Стратегии бесперебойного сотрудничества Микро-фронтенды — это быстро растущая тенденция в сфере фронтенда, гарантирующая, что удовольствие не ограничивается исключительно бэкэнд-системами..

    Декларативное и функциональное программирование в стиле LINQ с использованием JavaScript с использованием каррирования и генератора ...
    LINQ - одна из лучших функций C #, которая обеспечивает элегантный способ написания кода декларативного и функционального стиля, который легко читать и понимать. Благодаря таким функциям ES6,..

    Структуры данных в C ++ - Часть 1
    Реализация общих структур данных в C ++ C ++ - это расширение языка программирования C, которое поддерживает создание классов, поэтому оно известно как C с классами . Он используется для..

    Как я опубликовал свое первое приложение в App Store в 13 лет
    Как все началось Все началось три года назад летом после моего четвертого класса в начальной школе. Для меня, четвертого класса, лето кажется бесконечным, пока оно не закончится, и мой отец..