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

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

  2. 陈敏 Java课设实验报告

    1.团队课程设计博客链接 http://www.cnblogs.com/ohanna/p/7064305.html 2.个人负责模板或任务说明 1.负责完成主界面 2.随机数的产生, 3.数字大小的比 ...

  3. PHP连接数据_insert_id介绍

    对于自增长的主键列不好取值的情况,php提供了一个变量来取值,insert_id $db = new MySQLi("localhost","root",&qu ...

  4. Java: AutoCloseable接口

    K7 增加了一些新特性,其中报错AutoCloseable 等.新特性包括如下,下面主要说说AutoCloseable . 在JDK7 中只要实现了AutoCloseable 或Closeable 接 ...

  5. man page里面函数后面的括号中的数字代表的含义。

    Linux下最通用的领域及其名称及说明如下:领域 名称 说明 1 用户命令, 可由任何人启动的. 2 系统调用, 即由内核提供的函数. 3 例程, 即库函数. 4 设备, 即/dev目录下的特殊文件. ...

  6. powerdesigner逆向工程 oracle

    我们已经有了数据库,希望使用powerdesigner工具生成pdm文件. 本文使用的版本是 15.0 1,  File-->Reverse Engineer-->Database... ...

  7. Oracle-表的字段增加修改删除操作

    表结构修改 ALTER TABLE SCOTT.TEST RENAME TO TEST1--修改表名 ALTER TABLE SCOTT.TEST RENAME COLUMN NAME TO NAME ...

  8. Promise小书(长文)

    promise基础 Promise是异步编程的一种解决方案.ES6 Promise的规范来源于Promises/A+社区,它有很多版本的实现. Promise比传统的解决方案(回调函数和事件)更合理和 ...

  9. WebSocket部署服务器外网无法连接解决方案

    首先要说的是我遇见的问题: WebSocket connection to 'ws://www.xxxx.com/xxx/xx' failed: Error during WebSocket hand ...

  10. Apache CXF入门

    CXF简介 Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了.CXF 继承了 Celtix 和 XFire 两大 ...