【问题标题】:Creating a DropDownList in MVC that still populates the model backing it在 MVC 中创建一个 DropDownList 仍然填充支持它的模型
【发布时间】:2017-10-11 21:55:36
【问题描述】:

我有一个名为 GoalTypes 的小型模型,其中包含“跑步、骑自行车、体重……”等内容

public class GoalType
{
    public int Id { get; set; }
    public string Type { get; set; }
}

我还有一个模型,叫做目标 公开课目标 { 公共 int ID { 获取;放; }

[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime StartDate  { get; set; }

[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public  DateTime? EndDate { get; set; }

public string Type { get; set; }
public double Level { get; set; }

} 类型字段将由来自 GoalTypes 的类型字段填充。 在我的目标控制器中,我已经完成了:

public ActionResult Create()
{
    ViewBag.listOfGoals = new SelectList(db.GoalTypes, "Id", "Type");
    return View();
}

在我看来

<div class="form-group">
    @Html.LabelFor(model => model.Type, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownList("listOfGoals", "Select a Goal")
        @Html.ValidationMessageFor(model => model.Type, "", new { @class = "text-danger" })
    </div>
</div>

这会填充下拉列表,但如果我提交它,类型字段将留空

【问题讨论】:

  • 因为您创建了名为listOfGoals 的表单控件,但您的模型没有具有该名称的属性(其Type)。您的编辑数据因此始终使用视图模型。请参阅 this Q/A 中的代码以获取典型示例(您使用最坏的可能重载来生成不提供 2 路模型绑定或客户端验证的 &lt;select&gt; 元素)
  • 你可能想看看这个answer
  • 当您提交下拉列表时,您提交的是选定值,而不是复杂类型。您可以在提交时检查表单集合吗?
  • @CeriWestcott 好吧,听起来好像您需要 javascript 来帮助您解决这个问题。也许我误解了,但听起来好像您需要挂钩下拉列表的 onselect 事件以使用新的选定类型更新表单,也许将部分视图注入到表单中。我不确定...

标签: c# asp.net-mvc


【解决方案1】:

@Html.DropDownList("listOfGoals", "Select a Goal") 生成一个这样的选择元素:

<select name="listOfGoals" id="listOfGoals"></select> 

但您尝试在提交时将下拉列表绑定到模型中的 Type 属性,

因此,您需要将其更改为:

@Html.DropDownListFor(model => model.Type, (IEnumerable<SelectListItem>)ViewBag.listOfGoals, "Select a Goal")

@Html.DropDownListFor("Type", (IEnumerable<SelectListItem>)ViewBag.listOfGoals, "Select a Goal")

现在,select 是使用 name 属性作为“类型”创建的,DefaultModelBinder 可以将其绑定到 POST 操作中的属性。

此外,正如斯蒂芬建议的那样,您需要将 Type 更改为 int。因为提交的是选中的optionvalue,而不是文本。

public int Type { get; set; }

【讨论】:

    【解决方案2】:

    您必须将@ViewBag 传递给@Html.DropDownList,如下所示:

    @Html.DropDownList("listOfGoals", ViewBag.listOfGoals)
    

    或创建一个助手:

    public class MyHelpers{
       public static SelectList DropDownListGoalTypes(int? selected) {
            var list = db.GoalType.ToList();
            return new SelectList(list, "Id", "Type", selected);
       } 
     } 
    

    查看:

    @Html.DropDownListFor(x => x.Id, MyHelpers.DropDownListGoalTypes(Model.Id))
    

    【讨论】:

    • 如果listOfGoalsViewBag docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions/… 中可用,则没有必要
    • 在这种情况下,视图似乎不是类型化视图。
    • 即使使用第二个参数也不是强类型。我想你误解了我的意思。如果您在控制器中填充ViewBag.listOfGoals,并且视图中有@Html.DropDownList("listOfGoals"),它将按原样工作。无需像您在答案的第一部分中建议的那样明确添加(SelectList)ViewBag.listOfGoals
    • 我明白了,不用选角了。
    • 我不知道为什么它被否决了,一旦它给出了答案,并且上面的代码有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    相关资源
    最近更新 更多