本文参考:http://www.cnblogs.com/willick/p/3434483.html

1、Model验证用于在实际项目中对用户提交的表单的信息进行验证,MVC对其提供了很好的支持。

2、ModelState 是 Controller 抽象类的一个属性,它是 MVC 处理完验证时要使用的一核心对象,提供了对验证结果的存、取和判断。所以验证用户提交的数据,最直接的方法是在Action方法中使用 ModelState 对Model对象的属性值自行判断合法性。示例:

[HttpPost]
public ViewResult MakeBooking(Appointment appt)
{
if (string.IsNullOrEmpty(appt.ClientName))
{
ModelState.AddModelError("ClientName", "Please enter your name"); //ModelState.AddModelError用于添加错误信息
}
if (ModelState.IsValidField("Date") && DateTime.Now > appt.Date) //ModelState.IsValidField 方法用于检查用户提交的值是否能够被Model Binder成功赋值给指定的属性
{
ModelState.AddModelError("Date", "Please enter a date in the future");
}
if (!appt.TermsAccepted)
{
ModelState.AddModelError("TermsAccepted", "You must accept the terms");
}
if (ModelState.IsValid)
{
return View("Completed", appt);
} else
{
return View();
}
}

3、验证消息的显示,可以简单的分为两种,一种是Model级的,另一种是属性级的。Model级示例:

@using (Html.BeginForm()) {
@Html.ValidationSummary()
<p>Your name: @Html.EditorFor(m => m.ClientName)</p>
...
}
//Html.ValidationSummary()还有三些重载方法:Html.ValidationSummary(bool) 、 Html.ValidationSummary(string) 和 Html.ValidationSummary(bool, string) 。
//第一个是当参数为true时,只显示Model级的验证消息(如果 ModelState.AddModelError 方法的第一个参数没有指定属性名称,则为Model级的);第二个是为所有的验证消息显示一个标题;第三个是前两个的结合。

属性级示例:

@using (Html.BeginForm())
{
@Html.ValidationSummary(true)
<p>@Html.ValidationMessageFor(m => m.ClientName)</p>
<p>Your name: @Html.EditorFor(m => m.ClientName)</p>
<p>@Html.ValidationMessageFor(m => m.Date)</p>
<p>Appointment Date: @Html.EditorFor(m => m.Date)</p>
<p>@Html.ValidationMessageFor(m => m.TermsAccepted)</p>
<p>@Html.EditorFor(m => m.TermsAccepted) I accept the terms & conditions</p>
<input type="submit" value="Make Booking" />
}

4、处理在Action方法中进行验证,默认的ModelBinder在对值进行绑定时也有验证处理。示例:

[HttpPost]
public ViewResult MakeBooking(Appointment appt)
{
if (ModelState.IsValid)
{
return View("Completed", appt);
} else
{
return View();
}
}

5、对于MVC模式来说,如果把验证的规则放在自定义的 Model Binder 类中似乎并不合适。更多的时候我们会选择使用元数据的方式把验证的规则放在Model类中。示例:

public class Appointment
{
[Required]
public string ClientName { get; set; } [DataType(DataType.Date)]
[Required(ErrorMessage="Please enter a date")]
  public DateTime Date { get; set; } [Range(typeof(bool), "true", "true", ErrorMessage = "You must accept the terms")]
  public bool TermsAccepted { get; set; }
}

MVC内置的验证特性如下图:

6、我们也可以通过继承ValidationAttribute类自定义验证特性。示例:

public class MustBeTrueAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
return value is bool && (bool)value;
}
}

7、我们也可以继承内置的特性自定义验证特性。示例

public class FutureDateAttribute : RequiredAttribute
{
public override bool IsValid(object value)
{
return base.IsValid(value) && ((DateTime)value) > DateTime.Now;
}
}

8、Model级别的自定义验证。示例:

//Joe这个人星期一这天不能预约
public class NoJoeOnMondaysAttribute : ValidationAttribute
{
public NoJoeOnMondaysAttribute()
{
ErrorMessage = "Joe cannot book appointments on Mondays";
} public override bool IsValid(object value)
{
Appointment app = value as Appointment;
if (app == null || string.IsNullOrEmpty(app.ClientName) || app.Date == null)
{
return true;
}
else
     {
return !(app.ClientName == "Joe" && app.Date.DayOfWeek == DayOfWeek.Monday);
}
}
}
[NoJoeOnMondays]
public class Appointment
{
...
}

9、Model 的自验证,即在 Model 类内部编写验证逻辑方法,通过实现 IValidatableObject 接口来告诉 MVC 该某个 Model 是否为自验证的 Model。示例:

public class Appointment : IValidatableObject 
{
public string ClientName { get; set; }
[DataType(DataType.Date)]
public DateTime Date { get; set; }
public bool TermsAccepted { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
List<ValidationResult> errors = new List<ValidationResult>();
if (string.IsNullOrEmpty(ClientName)) {
errors.Add(new ValidationResult("Please enter your name"));
}
if (DateTime.Now > Date) {
errors.Add(new ValidationResult("Please enter a date in the future"));
}
if (errors.Count == && ClientName == "Joe" && Date.DayOfWeek == DayOfWeek.Monday) {
errors.Add(new ValidationResult("Joe cannot book appointments on Mondays"));
}
if (!TermsAccepted) {
errors.Add(new ValidationResult("You must accept the terms"));
}
return errors;
}
}

如果一个 Model 实现了 IValidatableObject 接口,MVC 会在 Model Binder 为 Model 的每个属性赋值后调用Validate方法。相对于在 Action 方法中的验证,这种 Model 自验证更为灵活,而且把验证逻辑放在对应的Model中,保证了代码的一致性,方便维护。

10、客户端验证在Web.config中有两个开关,默认都是启用的,如下:

<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>

要启用客户端验证,这两个值都需要设为true。你也可以在单个的View中通过设置HtmlHelper.ClientValidationEnabled 和 HtmlHelper.UnobtrusiveJavaScriptEnabled的值来开启或关闭客户端验证。启用时还需要包含三个JS引用:

  • /Scripts/ jquery-1.7.1.min.js
  • /Scripts/ jquery.validate.min.js
  • /Scripts/ jquery.validate.unobtrusive.min.js

当我们启用客户端验证后,要使用起来,最简单的方便是对Model应用验证特性,如Required、Range等。为了演示,我们修改 Appointment 类如下:

public class Appointment
{
[Required]
[StringLength(10, MinimumLength = 3)]
public string ClientName { get; set; } [DataType(DataType.Date)]
public DateTime Date { get; set; } public bool TermsAccepted { get; set; }
}

这里的验证规则是通过后台指定的。但并不是所有后台使用的验证都有对应的客户端验证,例如 action 中的验证、应用Model级的验证特性和Model的自验证都是没有客户端验证的。

     Tips:使用 MVC 提供的客户端验证的好处:不用写 JavaScript 代码;用户可以即时的看到验证消息,更快地得到反馈,如果用户禁用了JavaScript, MVC 就会走后台验证。

11、Remote 验证实际上就是通过 Ajax 实现的,只是被MVC封装好了,用起来简单多了,也不需要写 JavaScript 代码。示例:

//1、定义验证方法
public JsonResult ValidateDate(string Date) {
DateTime parsedDate;
if (!DateTime.TryParse(Date, out parsedDate)) {
return Json("Please enter a valid date (yyyy/mm/dd)", JsonRequestBehavior.AllowGet);
}
else if (DateTime.Now > parsedDate) {
return Json("Please enter a date in the future", JsonRequestBehavior.AllowGet);
}
else {
return Json(true, JsonRequestBehavior.AllowGet);
}
} //2、使用
public class Appointment
{
public string ClientName { get; set; } [DataType(DataType.Date)]
[Remote("ValidateDate", "Home")]
public DateTime Date { get; set; } public bool TermsAccepted { get; set; }
}

效果上和客户端验证差不多,但验证的处理是在 Controller 中的 Action 中发生的。应用 Remote 特性的字段,每次改变它的值都会调用一次后台,所以从某种意义上来说,我们应该尽量避免使用这种验证,除了那种不得不与后台交互的验证,如检查一个用户名是否已经存在。

【ASP.NET MVC 学习笔记】- 17 Model验证的更多相关文章

  1. ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现

    ASP.NET MVC 学习笔记-2.Razor语法   1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...

  2. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  3. ASP.NET MVC学习笔记-----Filter2

    ASP.NET MVC学习笔记-----Filter(2) 接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用 ...

  4. ASP.NET MVC学习笔记-----Filter

    ASP.NET MVC学习笔记-----Filter(1) Filter类型 接口 MVC的默认实现 Description Authorization IAuthorizationFilter Au ...

  5. ASP.NET MVC学习笔记-----Filter(2)

    接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用,它需要实现IActionFilter接口: public ...

  6. ASP.NET MVC 学习笔记(1)

    从头开始系统地学习ASP.NET MVC 为什么要学习ASP.NET MVC?原因很多,可以先来看一下最早的ASP.NET WebForm的一些缺点: 传说中面试经常要问到的ASP.NET WebFo ...

  7. ASP.NET MVC5 学习笔记-3 Model

    1. Model 1.1 添加一个模型 注意,添加属性时可以输入"prop",会自动输入代码段. public class CheckoutAccount { public int ...

  8. ASP.NET MVC学习笔记(二)笔记

    接下来我们一起了解ASP.NET MVC的最重要的核心技术,了解ASP.NET MVC的开发框架,生命周期,技术细节. 一.Routing与ASP.NET MVC生命周期 1.Routing——网址路 ...

  9. ASP.NET MVC学习笔记(一) 从路由开始创建mvc

    之前一篇写一半发现版本太老了,是基于mvc2的. 两本参考书编写的顺序各方面都不太一样.决定重新写一篇. 我这篇文章基于mvc5,vs2015 参考书:Will保哥的ASP.NET MVC4开发指南 ...

随机推荐

  1. 201521123101 《Java程序设计》第13周学习总结

    1. 本周学习总结 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu.edu.cn,分析返回结果有何不同?为什么会有这样的不同? 1.2 te ...

  2. 201521123099 《Java程序设计》第13周学习总结

    本周学习总结 书面作业 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu.edu.cn,分析返回结果有何不同?为什么会有这样的不同? 1.2 telnet bbs. ...

  3. 万物皆对象的JavaScript

    写在前面: 经过前段时间对于H5语言的学习,开始慢慢适应现在的生活节奏和代码语言.从一开始的毫无头绪到现在可以大概地写出部分的网站静态页面,用了两个周的时间.作为一个之前从未接触过计算机语言的初学者来 ...

  4. 【C# in depth 第三版】温故而知新(2)

    声明 本文欢迎转载,原文地址:http://www.cnblogs.com/DjlNet/p/7522869.html 前言 我们接了上一篇的未完待续,接着我们的划重点之行.....哈哈 理解:LIN ...

  5. python实例编写(7)---测试报告与测试套件(多个py文件,1个py文件内多个用例)

    一.  一个.py文件批量执行测试用例(一个.py文件下多个用例执行) 如果直接使用:unittest.main(),则按字母顺序执行, 对于前后之间又依赖关系的用例,需要按特定的顺序执行,则使用 s ...

  6. python实例编写(2)--等待,一组对象,层级元素,frame对象处理

    一.设置等待 #coding=utf-8 from selenium import webdriver from selenium.webdriver.support.ui import WebDri ...

  7. Ubuntu Server 12.04安装图解教程

                                                                                                Ubuntu S ...

  8. webpack2进阶之多文件,DLL,以及webpack-merge

    本需要对webpack已有一定的了解,如果你没接触过webpack或者刚刚接触webpack,可以考虑先看一下我的这篇教程. 入门教程 1.打包多文件 之前,当需要打包多个而文件时,我是这么写的: m ...

  9. hadoop源码import到eclipse工程

    1.解压hadoop-1.1.2.tar.gz,重点在src文件夹 2.在eclipse中通过菜单栏创建一个java工程,工程名随便 3.在创建的工程上,点击右键,在弹出菜单中选择最后一项,在弹出窗口 ...

  10. 再说AutoComplete

    一.简述 昨天support一同事,帮她的客户做类似下面的效果(自动完成): 以前在搜房的时候,弄过这个,调用楼盘字典: 这是一个小功能,也是一个大功能.因为它可以做大,也可以做小. 二.搜房的Aut ...