@ Html.DropDownList不发布回控制器

时间:2015-08-09 07:32:13

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

我第一次使用@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>

错误消息:

  

具有键&#39; ClassId&#39;的ViewData项。属于&#39; System.Collections.Generic.List`1 [[BusinessEntities.Class,BusinessEntities,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]&#39;但必须属于&#39; IEnumerable&#39;。

我希望将ClassId Student绑定并在发回Controller时自动填充。请帮我摆脱它。 感谢。

1 个答案:

答案 0 :(得分:2)

您需要为SelectList提供与您绑定的属性不同的名称(比如说)

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

然后

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

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

附注:不要使用Model => Model.XXX(大写字母M)和当前使用的DropDownistFor()作为2个参数,这些参数毫无意义。 "ClassId"会添加标签选项<option value="">ClassId</option>,最后一个,"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的类型不能是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
}