【问题标题】:Cannot change selected value for SelectList - MVC无法更改 SelectList 的选定值 - MVC
【发布时间】:2016-10-18 14:52:03
【问题描述】:

我正在尝试为视图中的表中的每条记录生成一个 DropDownList。我无法为下拉列表设置选定的值。

在控制器中,模型中每个用户的访问级别列表通过调用存储库中的方法来填充。我似乎无法完全正确地使用这种方法。我可以更改项目上的选定值,并且 accessLevels 选择了正确的值。但在视图中,这不是选定的值。如何设置选择列表的选定值?

我试过了:

存储库:

public IEnumerable<SelectListItem> GetSelectListAccessLevelsWithSelectedItem(string selectedAccessLevelID)
        {

            IEnumerable<SelectListItem> accessLevelsFromDB = DB.AccessLevels
              .Select(x => new SelectListItem
              {
                  Value = x.AccessLevelID.ToString(),
                  Text = x.Name
              });


            SelectListItem item = null;
            foreach (SelectListItem a in accessLevelsFromDB)
            {
                if (a.Value == selectedAccessLevelID)
                {

                    item = a;
                    a.Selected = true;
                }
            }

            var accessLevels = new SelectList(accessLevelsFromDB, item.Value);
            return accessLevels;
        }

还尝试返回 accessLevelsFromDB:

return accessLevelsFromDB;

查看:

@Html.DropDownList("Accesslevels", user.AccessLevelsWithSelectedItem, new { @class = "form-control", @name = "accessLevels"})

我是否正确使用了 SelectList 构造函数(IEnumerable、Object)?或者我还缺少什么?我试图谷歌,但仍然不明白我做错了什么。我看了这个问题SelectList Selected Value Issue - Stack Overflow,但这似乎不起作用。

更新:

这是模型:

public class EditCustomerViewModel
{
    public Customer Customer { get; set; }
    public int CustomerID { get; set; }
    public List<User> Users { get; set; }
    public List<UserToView> UsersToView { get; set; }
    public IEnumerable<SelectListItem> AccessLevelListForSelectedUser { get; set; }

}

更新 2:

我现在已经可以使用它并更新了我的模型和存储库。

型号:

public class EditCustomerViewModel
    {
        public Customer Customer { get; set; }
        public int CustomerID { get; set; }
        public List<UserToView> UsersToView { get; set; }

    }

存储库:

public IEnumerable<SelectListItem> GetSelectListAccessLevelsWithSelectedItem(string selectedAccessLevelID)
{
    IEnumerable<SelectListItem> accessLevelsFromDB = DB.AccessLevels
      .Select(x => new SelectListItem
      {
          Value = x.AccessLevelID.ToString(),
          Text = x.Name,
          Selected = x.AccessLevelID.ToString() == selectedAccessLevelID

      });
    return accessLevelsFromDB;
}

【问题讨论】:

  • 您的视图模型没有名为Accesslevels 的属性,因此您甚至没有绑定到任何东西。并且当绑定到属性时,您没有设置SelectListItemSelected 属性(它的属性值决定了选择的内容(该方法在内部构建自己的SelectList)。var accessLevels = new SelectList(accessLevelsFromDB, item.Value); 没有任何意义,因为@ 987654333@ 已经是SelectList
  • 并且视图模型在编辑时不应该包含数据模型
  • AccessLevelsWithSelectedItem 是模型中属性 UsersToView 中每个用户的属性,我正在尝试绑定到此属性。我应该将“AccessLevelsWithSelectedItem”作为下拉列表的第一个字符串参数还是我误解了?
  • 是的,但是如果你生成这个是一个循环,那么即使这样也不会绑定。您接受的答案完全具有误导性。 Selected 属性会被 DropDownList() 方法忽略,除非您没有绑定到某个属性 - 在您的情况下您没有(提交时它不会绑定到您的模型)。我建议你阅读MVC5 Razor html.dropdownlistfor set selected when value is in array

标签: c# asp.net-mvc selectlist


【解决方案1】:

这应该会为您的下拉菜单提供所选项目:

public IEnumerable<SelectListItem> AccessLevelsWithSelectedItem(string selectedAccessLevelID)
    {
        return DB.AccessLevels
          .Select(x => new SelectListItem
          {
              Value = x.AccessLevelID.ToString(),
              Text = x.Name,
              Selected = x.AccessLevelID.ToString() == selectedAccessLevelID
          });
    }

【讨论】:

    【解决方案2】:

    如果我们能看到您的视图使用的模型将会很有帮助。无论如何,你让这件事变得太难了。

    首先,DropDownList 只需要 IEnumerable&lt;SelectListItem&gt;。 Razor 将负责创建 SelectList 实例并绑定适当的选定值。事实上,无论如何它都会这样做,这就是为什么在您找到导致错误或没有绑定值的原因之前,您自己选择项目的尝试将徒劳无功。

    在这方面,一切都围绕ModelState,它由来自RequestViewBag/ViewData最终Model 的值组成。 “最终”部分很重要,因为请求或视图数据中的任何内容都将始终覆盖模型上设置的任何内容。

    换句话说,如果您的操作具有accessLevels 之类的参数,或者您正在设置ViewBag.AccessLevels 之类的内容。这些值将用作下拉菜单的“选定”值。

    同样,在这里查看视图模型会有所帮助,但一般来说,您应该将*For 助手系列与视图模型结合使用。理想情况下,您应该在模型上有一个属性,例如 AccessLevels,然后执行以下操作:

    @Html.DropDownListFor(m => m.AccessLevels, Model.AccessLevelOptions)
    

    其中AccessLevelOptions 将是IEnumerable&lt;SelectListItem&gt; 并包含可用的访问级别。有了它,您将永远不会对所选值有任何问题,因为 Razor 将处理所有事情,并且您强烈绑定到模型上的特定属性。只有当你开始使用字符串名称,与任何东西没有真正的联系时,事情才会开始出错。

    【讨论】:

    • 我更新了模型。但是如果我使用这个 @Html.DropDownListFor(m => m.AccessLevels, Model.AccessLevelOptions) 下拉菜单如何“知道”选择哪个值?我需要选择 Model.UsersToView.UserToView.AccessLevel 下模型中的特定值。
    • 这就是你应该绑定的。它根据ModelState 中的内容“知道”,因此您需要组合模型,使您绑定到的属性保持其拥有或应该拥有的值。
    【解决方案3】:

    您可以只传入硬编码字符串的 value 属性或该属性的模型值:

    @Html.DropDownList("Accesslevels", user.AccessLevelsWithSelectedItem, new { @class = "form-control", @name = "accessLevels", Value = "something" })
    

    @Html.DropDownList("Accesslevels", user.AccessLevelsWithSelectedItem, new { @class = "form-control", @name = "accessLevels", Value = Model.MyProperty })
    

    【讨论】:

    • 不应混淆value 属性。充其量,你是在掩盖一个更深层次的问题。在最坏的情况下,您会干扰正确的值绑定。
    • 我试过了,但它仍然没有改变下拉列表的选定值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    相关资源
    最近更新 更多