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

Gab*_*abe 26 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>
Run Code Online (Sandbox Code Playgroud)

和渲染的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>
Run Code Online (Sandbox Code Playgroud)

现在让我们做一个小改动.我将更改声明的id为不同的东西.

这是我的观点:

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

现在渲染的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>
Run Code Online (Sandbox Code Playgroud)

请注意,现在我得到一个选定的选项,它将是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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的行动:

[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;
  }
Run Code Online (Sandbox Code Playgroud)

Ric*_*lay 44

我认为问题是关于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列表中的选定值.

您的代码使用第二个重载,但指定了不存在的"value"属性("MultipleServicers").

要解决您的问题,请使用第一个重载:

<%= Html.DropDownList("IsMultipleServicers") %>
Run Code Online (Sandbox Code Playgroud)

或者,string MultipleServicers向视图模型添加属性并将其填充到控制器中.我推荐这个解决方案,因为它解决了初始显示,后期显示和将后期数据映射到视图/后期模型的几个问题:

public class ServiceViewModel : ViewModel 
{ 
     public string MultipleServicers { get; set; } 
     public List<SelectListItem> IsMultipleServicers { get; set; } 
}
Run Code Online (Sandbox Code Playgroud)

然后为您的HTML:

<%= Html.DropDownList(Model.MultipleServicers, Model.IsMultipleServicers) %>
Run Code Online (Sandbox Code Playgroud)

此技术也映射到MVC2:

<%= Html.DropDownListFor(x => x.MultipleServicers, Model.IsMultipleServicers) %>
Run Code Online (Sandbox Code Playgroud)


小智 9

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

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