【ASP.NET MVC 学习笔记】- 17 Model验证
本文参考: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验证的更多相关文章
- ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现
ASP.NET MVC 学习笔记-2.Razor语法 1. 表达式 表达式必须跟在“@”符号之后, 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 ...
- ASP.NET MVC学习笔记-----Filter2
ASP.NET MVC学习笔记-----Filter(2) 接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用 ...
- ASP.NET MVC学习笔记-----Filter
ASP.NET MVC学习笔记-----Filter(1) Filter类型 接口 MVC的默认实现 Description Authorization IAuthorizationFilter Au ...
- ASP.NET MVC学习笔记-----Filter(2)
接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用,它需要实现IActionFilter接口: public ...
- ASP.NET MVC 学习笔记(1)
从头开始系统地学习ASP.NET MVC 为什么要学习ASP.NET MVC?原因很多,可以先来看一下最早的ASP.NET WebForm的一些缺点: 传说中面试经常要问到的ASP.NET WebFo ...
- ASP.NET MVC5 学习笔记-3 Model
1. Model 1.1 添加一个模型 注意,添加属性时可以输入"prop",会自动输入代码段. public class CheckoutAccount { public int ...
- ASP.NET MVC学习笔记(二)笔记
接下来我们一起了解ASP.NET MVC的最重要的核心技术,了解ASP.NET MVC的开发框架,生命周期,技术细节. 一.Routing与ASP.NET MVC生命周期 1.Routing——网址路 ...
- ASP.NET MVC学习笔记(一) 从路由开始创建mvc
之前一篇写一半发现版本太老了,是基于mvc2的. 两本参考书编写的顺序各方面都不太一样.决定重新写一篇. 我这篇文章基于mvc5,vs2015 参考书:Will保哥的ASP.NET MVC4开发指南 ...
随机推荐
- 201521123121 《Java程序设计》第11周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 进程:每个进程都有独立的代码和数据空间,进程间的切换会有较大的开销,一个进程包含1--n个线程. 线程:同一类线程 ...
- Eclipse rap 富客户端开发总结(3):rcp/rap目前界面上的一些差异
1. Label和Button按钮的显示的差异 当Label 和 Button显示的文字过长显示不开的时候,rcp.rap的处理方式就不一样了,rap显示不开会自己截取掉后面的文字,rcp会在文字的中 ...
- 懒人小工具:自动生成Model,Insert,Select,Delete以及导出Excel的方法
在开发的过程中,我们为了节约时间,往往会将大量重复机械的代码封装,考虑代码的复用性,这样我们可以节约很多时间来做别的事情.最近跳槽到一节webform开发的公司,主要是开发自己公司用的ERP.开始因为 ...
- MySQL的数据备份以及pymysql的使用
一.MySQL的数据备份 语法: # mysqldump -h 服务器 -u用户名 -p密码 数据库名 > 备份文件.sql #示例: #单库备份 mysqldump -uroot -p123 ...
- SpringMVC第四篇【参数绑定详讲、默认支持参数类型、自定义参数绑定、RequestParam注解】
参数绑定 我们在Controller使用方法参数接收值,就是把web端的值给接收到Controller中处理,这个过程就叫做参数绑定- 默认支持的参数类型 从上面的用法我们可以发现,我们可以使用req ...
- 《Head First Java》读书笔记(1) - Java语言基础
<Head First Java>(点击查看详情) 1.写在前面的话 这本书的知识点说实话感觉有点散乱,但是贵在其将文字转换成了生动和更容易接受的图片,大量的比喻让人感受到了知识点的有趣之 ...
- java-annotation的简单介绍
package com.yangwei.shop.entity; /** * annotation作用 一是进行标识,二是进行约束 * *///必须让它在运行时能够执行@Retention(Reten ...
- C#ZIP根据路径读取压缩包内文件数量
/// <summary> /// 根据压缩包路径读取此压缩包内文件个数 /// </summary> /// <param name="strAimPath& ...
- eclipse通过maven构建web项目步骤说明
1. File -> New -> Other ,搜索maven,选择Maven Project,点击Next 2.这里不需要改继续Next 3.这里需要注意,需要选择maven-arc ...
- UI自动化测试简介及Selenium工具的介绍和环境搭建
自动化测试简介 1.1何为自动化测试? 是把以人为驱动的测试转化为机器执行的一种过程,它是一种以程序测试程序的过程.换言之,就是以程序实现的方式来代替手工测试. 1.2自动化测试分类 分为功能自动化测 ...