【问题标题】:DropDownList setting selected item in asp.net MVCDropDownList设置asp.net MVC中的选中项
【发布时间】:2010-03-09 16:17:55
【问题描述】:

我注意到在我看来是 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>

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

这是我的 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;
  }

【问题讨论】:

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


    【解决方案1】:

    我认为问题在于DropDownList 重载的混淆:

    1. Html.DropDownList(string name) 查找 name 的视图模型属性并键入 IEnumerable&lt;SelectListItem&gt;。它将使用列表中的选定项 (SelectListItem.Selected == true),除非存在同名的表单发布值。

    2. Html.DropDownList(string name, IEnumerable&lt;SelectListItem&gt; 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) %>
    

    【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 我之前不得不使用这种方法进行快速修复,但我认为最好稍后再返回并重构您的视图模型以更好地利用 Html.DropDownList 的预期用途(如令人困惑)
    【解决方案3】:

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

    【讨论】:

    • 很好地解释了正在发生的事情!我自己选择了你的默认做法——似乎是让事情变得明确的最好方法,并简化了 SelectListItem 值的生成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-17
    • 1970-01-01
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 2016-07-12
    相关资源
    最近更新 更多