DropDownList设置asp.net MVC中的选定项

时间:2010-03-09 16:17:56

标签: asp.net-mvc drop-down-menu

我注意到在我看来asp.net MVC中的一个错误,或者只是我做错了什么。我目前正在使用1.0,所以这可能会在2.0版本中得到解决。但不管怎样,我们走了。

当我的视图模型具有与下拉列表的声明ID同名的属性时,将忽略所选项目,并且渲染的html没有选择任何内容。 不确定我是否做错了,但更改ID的名称可以解决问题。我简化了这个例子,希望它很清楚,否则请告诉我。

以下是我的观点,其中声明的ID与模型中的列表名称相同:

<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>

现在让我们做一个小改动。我会将声明的ID更改为不同的内容。

这是我的观点:

<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>

请注意,现在我得到一个选定的选项,它将是List中的第二个元素。

以下是我的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 个答案:

答案 0 :(得分: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列表中的选定值。

  3. 您的代码使用第二个重载,但指定了一个不存在的“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) %>
    

答案 1 :(得分:9)

我使用Html.DropDownList(字符串名称,IEnumerable selectList)重载遇到了同样的问题。看来我的模型具有与下拉列表名称相同的属性。在这种情况下,MVC偏爱我的Model的属性值而不是IEnumerable中每个条目的Selected属性。

解决方案是使用与属性名称不匹配的下拉列表的名称。另一个解决方案是编写我自己的扩展方法,忽略模型和视图状态,而是始终尊重所选属性。

答案 2 :(得分:2)

DropDownList助手从模型中提取默认值。在第一种情况下,模型中与名称对应的值是SelectList - 这与列表中的任何项都不匹配,它是列表,因此不选择任何值。在第二个示例中,您的模型不包含具有该名称的属性,因此无法使用模型中的值,并且它默认为SelectList本身中指示的状态。通常情况下,我将在模型上为所选值设置一个属性 - 这将成为默认值 - 以及另一个表示列表潜在值的属性。