【问题标题】:@Html.DropDownListFor not posting back to controller@Html.DropDownListFor 不回发到控制器
【发布时间】:2015-11-01 07:51:47
【问题描述】:

我是第一次使用@Html.DropDownListFor。代码如下。

型号:

class Student
{
    [Required]
    [Display(Name = "Name")]
    public string Name { get; set; }

    [Required]
    [Display(Name = "Roll Number")]
    public string RollNumber { get; set; }

    [Required]
    [Display(Name = "ClassId")]
    public int ClassId { get; set; }

}

class Class
{
    [Required]
    [Display(Name = "ClassId")]
    public string RollNumber { get; set; }

    [Required]
    [Display(Name = "ClassName")]
    public string RollNumber { get; set; }
}

控制器:

public ActionResult Create()
{
    Student student = new BusinessEntities.Student();
    List<Class> classes = GetAllClasses();
    ViewBag.ClassId = new SelectList(classes, "ClassId", "ClassName");
    return View(student);
}

[HttpPost]
public ActionResult Create(BusinessEntities.Student student)
{
   if (ModelState.IsValid)
   {
      //Integer has 0 by default. But in our case if it contains 0, 
      //means no class selected by user
      if(student.ClassId==0)
      {
        ModelState.AddModelError("ClassId", "Select Class to Enroll in");
        return View(student);
      }
    }
}

学生创建视图:

<form  method="post">
    Select Class : 
    @Html.DropDownListFor(Model=>Model.ClassId,ViewBag.ClassId as IEnumerable<SelectListItem>, "ClassId","ClassName")
    @Html.ValidationMessageFor(Model => Model.ClassId)
    <input type="submit" value="Submit" />
</form>

错误信息:

具有键“ClassId”的 ViewData 项的类型为“System.Collections.Generic.List`1[[BusinessEntities.Class, BusinessEntities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'但必须是“IEnumerable”类型。

我希望Student 中的ClassId 在发布回控制器时自动绑定和填充。请帮我摆脱它。 谢谢。

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-mvc-3 razor


    【解决方案1】:

    您需要为 SelectList 指定一个与您绑定到的属性不同的名称(例如)

    ViewBag.ClassList = new SelectList(classes, "ClassId", "ClassName");` 
    

    然后

    @Html.DropDownListFor(m => m.ClassId, ViewBag.ClassList as IEnumerable<SelectListItem>)
    

    然后确保如果您返回视图(例如,如果ModelState 无效),则重新填充SelectList(就像您在 GET 方法中所做的那样)。当前,当您返回视图时,它是 null 导致错误,因为如果第二个参数是 null 后备是帮助程序期望第一个参数是 IEnumerable&lt;SelectListItem&gt; (但它不是 - 它的 typeof @987654329 @)

    旁注:不要使用 Model =&gt; Model.XXX(大写 M)和您当前使用的 DropDownistFor() 作为 2 个没有意义的参数。 "ClassId" 将添加一个标签选项 &lt;option value=""&gt;ClassId&lt;/option&gt; 而最后一个 ,"ClassName" 不会做任何事情。

    编辑

    此外,您的

    if(student.ClassId==0)
    {
        ModelState.AddModelError("ClassId", "Select Class to Enroll in");
        return View(student);
    }
    

    有点无意义。 student.ClassId 永远不会是 0,除非您的 GetAllClasses() 中的一项具有 ClassId = 0。你应该使用

    [Required(ErrorMessage = "Select Class to Enroll in")] // add error message here
    public int ClassId { get; set; }
    

    在视图中

    @Html.DropDownListFor(m => m.ClassId, ViewBag.ClassList as IEnumerable<SelectListItem>, "--please select--")
    

    这将创建值为null 的第一个选项。如果选择了此选项,则DefaultModelBinder 将尝试设置ClassId = null 的值,但失败(因为int 的typeof 不能是null)并添加ModelState 错误并且ModelState 变为无效。

    POST方法中的

    [HttpPost]
    public ActionResult Create(BusinessEntities.Student student)
    {
      if (!ModelSTate.IsValid)
      {
        ViewBag.ClassList = // repopulate select list
        return View(student);
      }
      // Save and redirect
    }
    

    【讨论】:

    • 另请参阅有关 POST 方法中代码的更新
    猜你喜欢
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多