2010-03-09 6 views
26

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

Когда у модели моего представления есть свойство, имя которого совпадает с объявленным идентификатором для выпадающего списка, выбранный элемент игнорируется, а отображаемый 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; 
    } 

ответ

43

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

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

  2. Html.DropDownList(string name, IEnumerable<SelectListItem> selectList) использует предметы от selectList, но не их выбранные значения. Выбранный найден путем разрешения name в модели представления (или данных для публикации) и сопоставления ее с SelectListItem.Value. Даже если значение не может быть найдено (или равно null), оно все равно не будет использовать выбранное значение из списка 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) %> 
+0

Желаю, чтобы это было более очевидно ... Но теперь это имеет смысл. Спасибо – ppumkin

+0

Я бы порекомендовал вам все это: http://www.c-sharpcorner.com/UploadFile/4d9083/creating-simple-cascading-dropdownlist-in-mvc-4-using-razor/ – Umitk

2

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

+0

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

9

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

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

+1

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

Смежные вопросы