本文参考: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. 201521123062 《Java程序设计》第13周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...

  2. 201521123114 《Java程序设计》第10周学习总结

    1. 本章学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 1. 创建线程方式: 定义Thread的子类 定义实现Runnable接口的类,实现run() 2. 调用s ...

  3. Python学习笔记011_模块_标准库_第三方库的安装

    容器 -> 数据的封装 函数 -> 语句的封装 类 -> 方法和属性的封装 模块 -> 模块就是程序 , 保存每个.py文件 # 创建了一个hello.py的文件,它的内容如下 ...

  4. 交互模式下测试python代码及变量的四则运算

    在交互模式下,python代码可以立即执行,所以这很方便我们进行代码测试 1.命令窗口,输入python (如果没配置环境变量则需带python安装目录的绝对路径) >>> 这个就是 ...

  5. CSS3的颜色渐变效果

    在 animate.css寻找自己想要的动态效果,看到标题Animate.css和按钮Animate it的颜色在逐渐变化,觉得蛮有趣的,把控制变化的相关代码扒了下来,自己分析实现一波. 一开始认为使 ...

  6. bootstrap 表单样式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 【京东详情页】——原生js学习之匿名函数

    一.引言 在js模块中,要给每一个功能封装一个匿名函数.为了更好的理解什么是匿名函数,为什么要用匿名函数,我做了一些查阅和学习. 二.匿名函数 什么是:在创建时,不被任何变量引用的函数. 为什么:节约 ...

  8. Spring 3.x 读书笔记

    第一:如果使用BeanFactory作为Spring Bean的工厂类,则所有的bean都是在第一次使用该Bean的时候实例化 第二:如果使用ApplicationContext作为Spring Be ...

  9. java集合系列——List集合之Vector介绍(四)

    1. Vector的简介 JDK1.7.0_79版本 Vector 类可以实现可增长的对象数组.与数组一样,它包含可以使用整数索引进行访问的组件.但是,Vector 的大小可以根据需要增大或缩小,以适 ...

  10. TETeLasr Cutting System 开机回零问题

    TETeLasr Cutting System 开机回零问题    :打开 "轴信息"    :打开 加工参数-->机器参数-->脉冲当量: X轴==4000 Y轴== ...