模型验证
一.模型验证简介
模型验证(Model Validation):即确保我们所接收到的数据适合模型绑定,并在不合适时,提醒用户,以帮助他们修正问题的过程。
准备一个简单的示例,用来介绍模型验证。
二.准备一个简单的示例
新建一个简单的MVC3空应用程序,并在Models文件夹下新建一个简单的Person类:
public class Person { public string Name { get; set; } [DataType(DataType.DateTime)] public DateTime Birthday { get; set; } public bool HasBrotherOrSister { get; set; } }
编译一下项目,在Controller文件夹下新建一个控制器HomeController,修改默认的Index方法,并为其新建一张基于Person类的强类型视图:
public ActionResult Index(Person person) { if (person==null || person.Name == null) { person = new Person { Name = "Input your name!", Birthday = DateTime.Parse("1987-2-1"), HasBrotherOrSister = false }; } return View(person); }
@model ModelValidation.Models.Person @{ ViewBag.Title = "Index"; } <h2>Index</h2> @using (Html.BeginForm()) { <p>Your Name:@Html.EditorFor(n=>n.Name)</p> <p>Your BirthDay:@Html.EditorFor(b=>b.Birthday)</p> <p>@Html.EditorFor(b=>b.HasBrotherOrSister) You have Brother/Sister</p> <input type="submit" value="Register" /> }
编译运行,看到如下界面,并修改其值,点击Register,值随之变化,证明示例成功进行了模型绑定,准备结束。
三.模型验证方式一
修改Index方法的代码如下:
public ActionResult Index(Person person) { //名字不能为空 if (string.IsNullOrEmpty(person.Name)) { ModelState.AddModelError("Name", "Please enter your name!"); } //生日不能大于当前日期(不符合日期格式的,会自动添加到异常中,这里无需手动添加) if (ModelState.IsValidField("Birthday") && DateTime.Now < person.Birthday) { ModelState.AddModelError("Birthday", "Please enter a date in the past!"); } if (ModelState.IsValid) { return View(person); } else { return View(); } }
修改对应的视图代码如下:
@model ModelValidation.Models.Person @{ ViewBag.Title = "Index"; } <h2>Index</h2> @using (Html.BeginForm()) { @Html.ValidationSummary() <p>Your Name:@Html.EditorFor(n=>n.Name)</p> <p>Your BirthDay:@Html.EditorFor(b=>b.Birthday)</p> <p>@Html.EditorFor(b=>b.HasBrotherOrSister) You have Brother/Sister</p> <input type="submit" value="Register" /> }
编译运行,名字不输入,日期手动填成大于当前日期,检测效果:
以上为模型验证的第一种方式。
附:
1.有时候我只想看到某些提示,不想看到所有的提示。如上面的示例,我只想看到第一条提示,却不想看到第二条提示,怎么办呢?
很简单,这里介绍一个关键词---“模型级错误”,只需将ModelState.AddModelError()首参数变成""即可:
public ActionResult Index(Person person) { //名字不能为空 if (string.IsNullOrEmpty(person.Name)) { ModelState.AddModelError("", "Please enter your name!"); //注意首参数改成了"",表示模型级错误 } //生日不能大于当前日期(不符合日期格式的,会自动添加到异常中,这里无需手动添加) if (ModelState.IsValidField("Birthday") && DateTime.Now < person.Birthday) { ModelState.AddModelError("Birthday", "Please enter a date in the past!"); } if (ModelState.IsValid) { return View(person); } else { return View(); } }
在修改视图代码:
@model ModelValidation.Models.Person @{ ViewBag.Title = "Index"; } <h2>Index</h2> @using (Html.BeginForm()) { @Html.ValidationSummary(true) //参数true表示只显示模型级错误;否则显示所有错误。 <p>Your Name:@Html.EditorFor(n=>n.Name)</p> <p>Your BirthDay:@Html.EditorFor(b=>b.Birthday)</p> <p>@Html.EditorFor(b=>b.HasBrotherOrSister) You have Brother/Sister</p> <input type="submit" value="Register" /> }
编译运行,不输入名字,将生日置成大于当前日期:
可见只提示了关于名字的错误,却没有提示生日大于当前日期的错误。
关于ValidationSummary方法,有不少重载,详见这里。
2.有时候我不希望错误提示显示在最上面,而是显示在对应的文本源附近,如何弄呢?
很简单,修改视图代码为:
@model ModelValidation.Models.Person @{ ViewBag.Title = "Index"; } <h2>Index</h2> @using (Html.BeginForm()) { <p>Your Name:@Html.EditorFor(n=>n.Name) @Html.ValidationMessageFor(n=>n.Name)</p> <p>Your BirthDay:@Html.EditorFor(b=>b.Birthday) @Html.ValidationMessageFor(b=>b.Birthday)</p> <p>@Html.EditorFor(b=>b.HasBrotherOrSister) You have Brother/Sister</p> <input type="submit" value="Register" /> }
注意不要将错误设置成1中的模型级错误,否则显示不出提示!
编译运行,构造输入错误,让其能够出提示:
以上,为模型验证方式一。
四.模型验证方式二
待续……