[asp.net-mvc]ViewBag 不将值传递到控制器与 MVC DropDownListFor

发布时间: 2017/3/25 14:34:50
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我正在试图建立相关模型/视图中的表我创建一个下拉列表的真正的困难时期。我客人模型具有对 PersonPrefix 模型的引用方式如下︰

来宾模式︰

public virtual PersonPrefix Prefix { get; set; }

PersonPrefix 模型︰

public class PersonPrefix
{

    [Key]
    public int PersonPrefixID { get; set; }
    [StringLength(6)]
    public string Abbreviation { get; set; }
    [StringLength(255)]
    public string Name { get; set; }
    public virtual ICollection<Guest> Guests { get; set; }

}

我已经完成下列操作,可以从数据库中获取数据并显示在下拉列表中︰

控制器︰

public ActionResult Create()
{
    ViewBag.PersonPrefixes = new SelectList(db.PersonPrefixes, "PersonPrefixID", "Abbreviation");
    return View();
} 

和我已经向职位添加前缀对象

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "GuestID,FirstName,MiddleName,Surname,BirthDate,SelectedPrefix")] Guest guest)
{
    if (ModelState.IsValid)
    {
        db.Guests.Add(guest);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(guest);
}

这是在视图中的相关代码到目前为止,但它不将值传递到控制器︰

  <div class="form-group">
        @Html.LabelFor(model => model.Prefix, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10" >
            @*@Html.DropDownListFor(m => m.Prefix,  new SelectList(ViewBag.PersonPrefixes, "Value", "Text", 1))*@
            @Html.DropDownListFor(m => m.Prefix,
            new SelectList(ViewBag.PersonPrefixes, "Value", "Text", 1))

        </div>
    </div>

谢谢你的帮助!!

解决方法 1:

您不能将绑定 <select> 到一个复杂的对象元素。所有 html 表单控件回都发一个单一的值 (或的情况下 <select multiple> 的值类型数组)。如果您选择选项值的 (说) 5,则 DefaultModelBinder 会尝试设置 guest.Prefix = 5; ,当然失败。

你需要将绑定到一个值类型 (例如 intstring 等)。你的情况你甚至不能绑定到 PersonPrefixIDPersonPrefix 因为验证会失败对其他性能的 PersonPrefix 。因为总是在编辑时,您应该使用包含只有这些属性的视图模型,您需要编辑。

public class GuestVM
{
  [Display(Name = "Prefix")]
  [Required(ErrorMessage = "Please select a prefix")]
  public int SelectedPrefix { get; set; }
  .... // other properties of Guest
  public SelectList PrefixList { get; set; }
}

控制器

public ActionResult Create()
{
  GuestVM model = new GuestVM();
  model.PrefixList = new SelectList(db.PersonPrefixes, "PersonPrefixID", "Abbreviation");
  .... // set other properties as required
  return View(model); // always return an instance of the model
}

视图

@Html.LabelFor(m => m.SelectedPrefix)
@Html.DropDownListFor(m => m.SelectedPrefix, Model.PrefixList, "--please select--")
@Html.ValidationMessageFor(m => m.SelectedPrefix)

然后在 POST 方法初始化新实例的 Guest 数据模型和映射及其属性从已过帐的视图模型以及最后保存的数据模型。

public ActionResult Create(GuestVM model)
{
  if (!ModelSTate.IsValid)
  {
    model.PrefixList = new SelectList(db.PersonPrefixes, "PersonPrefixID", "Abbreviation");
    return View(model);
  }
  // Initialize a new instance of the data model and set its properties
  Guest guest = new Guest()
  {
    FirstName = model.FirstName,
    MiddleName = model.MiddleName,
    .... // other properties
    Prefix = db.PersonPrefixes.Find(model.SelectedPrefix)
  };
  db.Guests.Add(guest);
  db.SaveChanges();
  return RedirectToAction("Index");
}

边注︰ 您不需要创建另一个 SelectList 在视图中 (其已经 SelectList ) 和最后一个参数在您尝试将选定的值设置为 1 忽略 (它是您绑定到,确定所选的选项的属性值) 所以如果你想要预先选择了一个带有 value="1" ,然后设置的值 SelectedPrefix = 1; 控制器之前将模型传递到视图中。

官方微信
官方QQ群
31647020