【问题标题】:DropDownListFor - does not select "Selected" valueDropDownListFor - 不选择“选定”值
【发布时间】:2012-03-23 01:13:18
【问题描述】:

关于DropDownListFor 未选择“Selected” 值的另一个问题。 这是代码:

型号:

public class CreateEditAccountModel
{
    [Required]
    [Display(Name = "Permission")]
    public int PermissionId { get; set; }
    public IEnumerable<SelectListItem> Permissions { get; set; }
}

控制器:

[HttpGet]
[Authorize]
public ActionResult EditAccount(int id)
{
    CreateEditAccountModel model = new CreateEditAccountModel();
    model.Permissions = PermissionsAll();
    return View("CreateEditAccount", model);
}

此时,如果我在返回行上设置断点,model.Permissions 包含正确的 IEnumerable&lt;SelectListItem&gt; 对象,其中包含多个项目且只有一个具有 Selected = true

查看:

@using (Html.BeginForm())
{
    @Html.DropDownListFor(m => m.PermissionId, Model.Permissions)
}

渲染:

<select id="PermissionId" name="PermissionId">
    <option value="">-- Select --</option>
    <option value="1">Permission one</option>
    <option value="2">Permission two</option>
</select>

由于某种原因,任何选项都没有 selected 属性,因此选择了第一个选项。

感谢任何帮助。


更新

看来这与article 有关。总结本文的解决方案,我需要确保属性名称(@html.DropDownList 的第一个参数)与模型的任何现有属性匹配。 谁能解释为什么会这样?

当我在视图中这样写时,它会正确呈现下拉:

@Html.DropDownList("PermissionIdNotMatching", Model.Permissions)

但是,这样做没有任何逻辑意义,因为我实际上希望 binder 能够将 select 元素的名称与模型属性匹配。否则我必须手动获取这样的值:Request.Form["PermissionIdNotMatching"];

有人有什么想法吗?


解决方案

查看接受的答案和对其的第一条评论。

【问题讨论】:

  • PermissionId 的值应该等于 Selected = true 的 SelectListItem.Value。尝试 model.PermissionId = Convert.ToInt32(lst.First(t => t.Selected).Value);我也遇到了与您相同的问题,令人惊讶的是,在编辑时选择了该值,从那里我认为 PermissionId 应该具有与所选 SelectListItem 的值相同的值。为我工作。

标签: asp.net-mvc-3 html.dropdownlistfor


【解决方案1】:

好的,让我们讨论一下你的例子,当 PermissionId 是 int 时。您发布了CreateEditAccountModel 类型的模型以供查看。当您创建此模型时,PermissionId 等于 0(默认值 int)。而DropDownListFor 在视图中得到这个值。因此,您没有选择的值。 使用字符串类型时,PermissionId 的默认值为 null,因此 `DropDownListFor 采用 SelectList 的默认值。

在这种情况下,PermissionId 最好使用int?Nullable&lt;int&gt; 类型。

【讨论】:

  • 你的解释是相关的。回过头来,当我问这个问题时,我不明白DropDownListFor 将首先评估PermissionId 的值,如果它不为空,它将选择该值。否则会考虑Model.Permissions
  • 这可能与问题有关,也可能与问题无关,但是当您说从 linq 创建一个 List 到实体并将 Int 转换为字符串值时,它可能对某人有用您正在使用 SqlFunctions.StringConvert 因为它不会为预选值呈现 selected = true 。不修剪会导致下拉列表具有如下值:value = "1"。
【解决方案2】:

当您使用@Html.DropDownListFor(m =&gt; m.PermissionId, Model.Permissions) 时,请确保您的模型中已经设置了 PermissionId - 即所选项目/id。此外,模型还包含一个 'selected' 属性:

var query = DatabaseContexts.Select(
            c => new SelectListItem
            {
                Value = c.Key,
                Text = c.Value,
                Selected = c.Key == currentUsed
            });

 PermissionId = that want to select;
 Permissions = query.AsEnumerable();

更新:

这里是 HttpGet 的完整示例:

在 HomeController.cs 中:

[HttpGet]
public ActionResult EditAccount(int id)
{
    CreateEditAccountModel model = new CreateEditAccountModel();

    var permissionsAll = new List<SelectListItem>
         {
             new SelectListItem
                 {
                     Value = "",
                     Text = "--please select--",
                     Selected = false
                 },
             new SelectListItem
                 {
                     Value = "1",
                     Text = "Permission one",
                     Selected = true
                 },
             new SelectListItem
                 {
                     Value = "2",
                     Text = "Permission two",
                     Selected = false
                 }
         };
    model.PermissionId = 1; //add this line
    model.Permissions = permissionsAll; // PermissionsAll();// -- get data from services or anywhere....
    return View("EditAccount", model);
}

CreateEditAccountModel.cs:

public class CreateEditAccountModel
{
    [Required]
    [Display(Name = "Permission")]
    public int PermissionId { get; set; }
    public IEnumerable<SelectListItem> Permissions { get; set; }

}

EditAccount.cshtml:

@using MvcApplication1.Models
@model CreateEditAccountModel
@{
   ViewBag.Title = "EditAccount";
 }

<h2>EditAccount</h2>
@using (Html.BeginForm())
{
   @Html.DropDownListFor(m => m.PermissionId, Model.Permissions)
}

运行应用程序并转到/home/editaccount/1,下拉菜单将默认选择“Permission one”。

我认为 PermissionId 必须是 type 'string' 是,System.Web.Mvc.SelectedListItem.Value 是 'string'

如果你想在用户在下拉列表中选择项目时做某事,你可能需要[HttpPost]。

顺便说一句:this link 对你有用吗?

【讨论】:

  • PermissionId 实际上已设置。我最初从模型中复制了一组错误的属性。请重新审核。
  • 在控制器中: CreateEditAccountModel model = new CreateEditAccountModel(); model.Permissions = PermissionsAll();模型.PermissionId = 1; /*选择的id */ return View("CreateEditAccount", model);在视图中:@Html.DropDownListFor(m => m.PermissionId, Model.Permissions);
  • xoyoja,你为什么要在 HttpGet 上给它赋值呢?在任何情况下,变量值都不应该影响下拉列表,因为它只是一个保存选定值的变量。我仍然尝试过,但没有帮助。感谢您的尝试!
  • xoyoja,感谢您的帮助。分配 model.PermissionId = 1; 没有帮助。不过,我已经找到了解决问题的方法,而且 PermissionId 的类型是 int。我已经用 UPDATE 部分更新了我的问题,其中显示了一些正在进行的思考和 SOLUTION 部分。关于 SelectList 的 ling 不适用于 HttpPost 是无关紧要的,因为我拥有它 HttpGet
  • @Dmitry,只需在 vs2010 中创建一个空的 asp.net mvc3 razor 应用程序,从“更新”部分粘贴我的代码,它就可以工作。 BTW:关于“为什么 PermissionId 变量必须是字符串类型才能使 DropDownListFor 工作”的问题,如果您不喜欢 DropDownListFor 的方法,您可以创建自己的“HtmlHelper.DropDownListFor”扩展方法,这很直接向前。 ASP.NET MVC 框架的所有组件都经过精心设计,可以轻松替换或定制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多