asp.net-mvc - MVC DropDownListFor 与 ViewBag 不将值传递给 Controller

标签 asp.net-mvc entity-framework viewbag dropdownlistfor

我在尝试在创建 View 中为相关模型/表设置下拉列表时遇到了很大的困难。我的 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; }

}

我已完成以下操作,以便能够从数据库获取数据并将其显示在下拉列表中:

Controller :

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);
}

这是迄今为止 View 中的相关代码,但它没有将值传递给 Controller ​​:

  <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>

感谢您的帮助!!

最佳答案

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

您需要绑定(bind)到值类型(例如 intstring 等)。在您的情况下,您甚至无法绑定(bind)到 PersonPrefixIDPersonPrefix因为 PersonPrefix 的其他属性验证将失败。与往常一样,在编辑时,您应该使用仅包含需要编辑的属性的 View 模型。

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; }
}

Controller

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的新实例数据模型并从发布的 View 模型映射其属性,最后保存数据模型。

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在 View 中(它已经是 SelectList )以及您尝试将所选值设置为 1 的最后一个参数被忽略(它的绑定(bind)属性的值决定选择哪个选项),因此如果您想使用 value="1" 预先选择一个选项,然后设置SelectedPrefix = 1;的值在将模型传递给 View 之前在 Controller 中。

关于asp.net-mvc - MVC DropDownListFor 与 ViewBag 不将值传递给 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30496003/

相关文章:

javascript - 无法看到警报 - mvc5 通过 TempData 进行引导

c# - ASP.Net MVC - 带集合的模型,提交

c# - 具有动态 Entity.Property 唯一检查的通用 ValidationAttribute(在运行时设置)

javascript - 检查 ViewBag 值是否为 null

asp.net-mvc - asp.net mvc3 razor 语法通过反射将模型转换为其子类

c# - ASP.NET MVC + EF 性能

.net - 使用 Entity Framework 在运行时更新数据库架构

css - 使用 ViewBag for Navigation 在 <li> 中动态插入类,具有子级依赖性(MVC)

asp.net-mvc - ViewData 和 ViewBag 在哪里?

asp.net-mvc - 模型数据注释 [DataType(DateType.Date)] 呈现 DatePicker 但隐藏我的值?