asp.net - @Html.DropDownListFor 不回发到 Controller

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

Controller :

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

学生创建 View :

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

错误消息:

The ViewData item that has the key 'ClassId' is of type 'System.Collections.Generic.List`1[[BusinessEntities.Class, BusinessEntities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' but must be of type 'IEnumerable'.

我希望在发回 Controller 时自动绑定(bind)并填充 StudentClassId。请帮助我摆脱它。 谢谢。

最佳答案

您需要提供SelectList与您绑定(bind)的属性不同的名称(例如)

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

然后

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

然后确保如果返回 View (例如 ModelState 无效),则重新填充 SelectList (正如您在 GET 方法中所做的那样)。目前当你返回 View 时,它是 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; }

并在 View 中

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

这将创建第一个选项,其值为 null 。如果选择此选项,则 DefaultModelBinder将尝试设置 ClassId = null 的值失败(因为 typeof 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
}

关于asp.net - @Html.DropDownListFor 不回发到 Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31901941/

相关文章:

c# - 即时生成 iOS list

c# - 编辑时禁用用户名验证

javascript - 如何添加特定于页面的脚本链接(使用母版页的 MVC)

c# - 找不到 View 。

c# - 如何根据某些条件隐藏特定的 jqueryui 选项卡?

c# - 使用elasticsearch进行搜索(包含)

asp.net-mvc - 我正在寻找有关自定义 MVC3 编辑器模板的高级资源

c# - 我应该将用户配置文件信息存储在缓存还是 session 中?

asp.net - 拒绝访问 web.config 中的 'admin' 文件夹

c# - 以对象列表作为属性的 MVC 模型