@ Html.DropDownList用于不发回到控制器 [英] @Html.DropDownListFor not posting back to controller

查看:107
本文介绍了@ Html.DropDownList用于不发回到控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我第一次使用@Html.DropDownListFor.代码在下面.

I am using @Html.DropDownListFor for the first time. Code is below.

型号:

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"类型.

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

我希望将Student中的ClassId绑定并在回发到Controller时自动填充.请帮助我摆脱它. 谢谢.

I want ClassId of Student be binded and populated automatically when posted back to Controller. Please help me to get rid of it. Thanks.

推荐答案

您需要给SelectList一个不同的名称,该名称是您绑定的属性(例如)

You need to give the SelectList a different name that the property your binding to (say)

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

然后

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

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

and then ensure if you return the view (for example if ModelState is invalid), that you repopulate the SelectList (as you have done in the GET method). Currently when you return the view, it is null resulting in an error, because if the second parameter is null the fallback is that the helper expects the first parameter to be IEnumerable<SelectListItem> (but its not - its typeof int)

侧面注意事项:不要使用Model => Model.XXX(大写M),并且当前使用的DropDownistFor()作为2个没有意义的参数. "ClassId"将添加标签选项<option value="">ClassId</option>,最后一个,"ClassName"将不执行任何操作.

Side notes: Do not use Model => Model.XXX (capital M) and your current use of DropDownistFor() as 2 parameters which make no sense. "ClassId" will add a label option <option value="">ClassId</option> and the last one ,"ClassName" will not do anything.

修改

此外,您的

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

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

is a bit pointless. student.ClassId will never be 0 unless one of the items in your GetAllClasses() has ClassId = 0. You should be using

[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的值,该值将失败(因为typeof int不能为null),并且添加了ModelState错误,并且ModelState变为无效.

which will create the first option with a value of null. If this option were selected, then the DefaultModelBinder will attempt to set the value of ClassId = null which fails (because typeof int cannot be null) and a ModelState error is added and ModelState becomes invalid.

POST方法中的

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

这篇关于@ Html.DropDownList用于不发回到控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆