DropDownList установка выбранного элемента в asp.net MVC - PullRequest
26 голосов
/ 09 марта 2010

Я заметил, что мне кажется ошибка в 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;
  }

Ответы [ 3 ]

43 голосов
/ 09 марта 2010

Я думаю, что проблема в путанице в отношении 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.

Ваш код использует вторую перегрузку, но указывает свойство «value», которое не существует («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) %>
9 голосов
/ 10 марта 2010

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

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

2 голосов
/ 09 марта 2010

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

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