我很难在我的创建视图中尝试为相关模型/表设置下拉列表。我的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;当然会失败。

您需要绑定到值类型(例如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;的值。

08-28 01:08