asp.net-mvc – MVC DropDownListFor,ViewBag没有将值传递给控制器

我真的很难在我的创建视图中设置一个下拉列表到相关的模型/表.我的Guest模型以下列方式引用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>

谢谢你的帮助!!

最佳答案 您无法绑定< select>元素到复杂的对象.所有html表单控件都回发单个值(或者在< select multiple>值类型数组的情况下).如果您选择了值为(例如)5的选项,则DefaultModelBinder将尝试设置guest.Prefix = 5;当然失败了.

您需要绑定到值类型(例如int,string等).在您的情况下,您甚至无法绑定到PersonPrefix的PersonPrefixID,因为验证将在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的最后一个参数(它的绑定属性的值决定了哪个选项)如果你想预先选择值为“1”的选项,那么设置SelectedPrefix = 1的值;在将模型传递给视图之前,在控制器中.

点赞