ASP.NET MVC之验证终结者篇
有时候我觉得,很多人将一个具体的技术细节写的那么复杂,我觉得没有必要,搞得很多人一头雾水的,你能教会别人用就成了,具体的细节可以去查MSDN什么的,套用爱因斯坦的名言:能在网上查到的就不要去记,用的时候拿过来就是。应用层面的东东,没必要深究,真正的核心已经被那些大胡子老外们搞定了,你要说你非想搞明白某个东东,那你可以把你的时间用在架构和管理上去,亦或是你也搞个编译器(搞swift语言的那家伙就是捯饬的这个)什么的,玩玩金融,甚至把把妹子都比你去研究一门最底层的技术细节强,我们常说面向抽象编程,说白了就是低层要依赖高层,所以还是研究点高端的东东对你以后有帮助!
言归正传,MVC验证走起,不过只此一篇,希望能讲多少是多少吧!
一、基于数据注解特性的验证
A、你如果想用数据注解特性,那就必须要引入以下命名空间:using System.ComponentModel.DataAnnotations;
可以注意到,这个命名空间不是以System.Web开头的,这也说明了它并不单单是为Web项目准备的,如何其它类型的项目都可以使用。
例如:对于一个注册用的model,在其上面用特性验证
using System.ComponentModel.DataAnnotations;
namespace Ctrip.Models
{
public class Register
{
[Required(ErrorMessage="用户名必须填写")]
[MinLength(,ErrorMessage="用户名长度过短")]
public String UserName { get; set; }
[DataType(DataType.Password)]
public String Password { get; set; }
[DataType(DataType.Password)]
[Compare("Password",ErrorMessage="密码要一致")]
public String RptPassword { get; set; }
public String Email { get; set; }
public DateTime BirthDate { get; set; }
}
}
注:错误消息还可以用占位符,体会一下好处在哪
[Required(ErrorMessage=”Your {} is required.”)]
public string Name { get; set; }
B、在view中用HtmlHelper的方法就可以实现客户端验证了(前提是要开启客户端验证)
@Html.ValidationSummary()会输出所有验证错误, 一般放在Form头处
@Html.ValidationMessageFor()是针对单个输入的验证
大概就是下面的格式:
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary()
<fieldset>
<legend>Registration Form</legend>
<ol>
<li>
@Html.LabelFor(m => m.UserName)
@Html.EditorFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)
</li>
<li>
@Html.LabelFor(m => m.Password)
@Html.EditorFor(m => m.Password)
@Html.ValidationMessageFor(m => m.Password)
</li>
<li>
@Html.LabelFor(m => m.Email)
@Html.TextBoxFor(m => m.Email)
@Html.ValidationMessageFor(m => m.Email)
</li>
<li>
@Html.LabelFor(m => m.BirthDate)
@Html.EditorFor(m => m.BirthDate)
@Html.ValidationMessageFor(m => m.BirthDate)
</li>
</ol>
<input type="submit" value="Register" />
</fieldset>
}
这个时候如果你不处理后端,只要客户端允许JS运行,就可以在客户端验证,而且是AJAX验证哦,不解释~
备注:客户端验证在哪里开启与关闭呢?在web.config里边,true or false,你说了算!
<appSettings>
<add key="ClientValidationEnabled" value="false" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
C、搞定后端验证
有些人说在控制器里边写一个专门的Valid()方法验证,我说这不是作死的节奏啊,有肉还吃豆腐?呵呵,说的就是下面这个东东ModelState.IsValid
[HttpPost]
public ActionResult Create(Register register)
{
if (ModelState.IsValid)
{
return RedirectToAction("Index", "Home");
}
return View(register);
}
D、验证特性特别多,想要看的自己上网查,或者反编译上面的那个命名空间就可以看到!
不过有两个特性比较特殊,是在System.Web.Mvc命名空间里边:
RemoteAttribute和CompareAttribute,CompareAttribute的用法上面的A中已有,下面举个RemoteAttribute的例子,就是我们在网站注册的时候,要求用户名不能重复,可以用这个RemoteAttribute实现,是异步的~
public class Employee
{
public int EmpId { get; set; }
[DisplayName("Employee Name")]
[Remote("IsEmployeeNameAvailable", "Validation")] //使用RemoteAttribute,指定验证的Controller和Action
public String EmployeeName { get; set; } }
然后你再写个Action就行了,由于比较简单这里就不再写了!
警告:这个RemoteAttribute是只进行客户端验证的,服务器端不验证的,所以如果某个用户屏蔽了客户端js那就没用了
注:正则表达式特性也很有用的,例如:
[RegularExpression(@”[A-Za-z0-._%+-]+@[A-Za-z0-.-]+\.[A-Za-z]{,}”,ErrorMessage=”Email doesn’t look like a valid email address.”)]
具体的正则表达式你可以上网搜~
二、自定义数据注解特性验证
先说说什么是双重验证?
其实就是客户端验证加服务器端验证而已~
为什么要双重验证?
首先,客户端验证能够直接响应客户,减少了服务器压力的同时还提高了用户体验,但是你永远不能信任来自客户端的信息(用户可以关闭浏览器的脚本功能,让你的js验证彻底不起作用),所以服务器端验证也是必须的~
常规验证可以通过上面列出的这些系统预定义ValidationAttribute特性来完成,但是在很多情况下我们需要通过创建自定义的ValidationAttribute特性来解决一些特殊的验证,而且这些自定义的特性在很多地方可以重用的!
你需要做的就是重写ValidationAttribute里边的方法IsValid()而已
举个栗子:
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions; namespace MvcValidation.Extension
{
public class EmailAttribute : ValidationAttribute
{
public const string reg = @"^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]+$"; public EmailAttribute()
{
} //重写基类方法
public override bool IsValid(object value)
{
if (value == null)
return true; if (value is string)
{
Regex regEx = new Regex(reg);
return regEx.IsMatch(value.ToString());
}
return false;
}
}
}
用的话,就是下面的样子:
[Email]
public string Email { get; set; }
注意:
此时的自定义的验证特性只支持后端验证,如果想支持前端jquery验证,还需要实现 IClientValidatable接口
所以改写一下:
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using System.Web.Mvc; namespace MvcValidation.Extension
{
public sealed class EmailAttribute : ValidationAttribute, IClientValidatable
{
public const string reg = @"^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]+$"; public EmailAttribute()
{
} //重写基类方法
public override bool IsValid(object value)
{
if (value == null)
return true; if (value is string)
{
Regex regEx = new Regex(reg);
return regEx.IsMatch(value.ToString());
}
return false;
} public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule rule = new ModelClientValidationRule
{
ValidationType = "email",
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
};
yield return rule;
}
}
}
注意:
ValidationType属性的值一定要小写,否则报错。
其实还没有结束呢,还要扩展JQuery函数(jQuery.validator.email.js文件)
//扩展方法
$.validator.addMethod("email", function (value, element) {
if (value == false) {
return true;
}
this.optional(element) || /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]+$/i.test(value);
}); //扩展方法注册
$.validator.unobtrusive.adapters.addBool("email");
其实实现IClientValidatable之后,就是为前端的Email输入input标签添加了一个data-val-email属性而已,属性中的“email”就是ValidationType = "email"中的名字。
三、带自我验证的模型
适用场景:不需要重用验证逻辑,只是针对某一个特定的模型进行验证。
这些带自我验证的模型实现了接口IValidatableObject,该接口定义在“System.ComponentModel.DataAnnotations”命名空间下。
public interface IValidatableObject
{
IEnumerable<ValidationResult> Validate( ValidationContext validationContext);
}
举个栗子:
public class Person: IValidatableObject
{
[DisplayName("姓名")]
public string Name { get; set; }
[DisplayName("性别")]
public string Gender { get; set; }
[DisplayName("年龄")]
public int? Age { get; set; }
public IEnumerable<ValidationResult> Validate( ValidationContext validationContext)
{
Person person = validationContext.ObjectInstance as Person;
if (null == person)
{
yield break;
}
if(string.IsNullOrEmpty(person.Name))
{
yield return new ValidationResult("'Name'是必需字段", new string[]{"Name"});
}
if (string.IsNullOrEmpty(person.Gender))
{
yield return new ValidationResult("'Gender'是必需字段", new string[] { "Gender" });
}
else if (!new string[]{"M","F"}.Any( g=>string.Compare(person.Gender,g, true) == ))
{
yield return new ValidationResult("有效'Gender'必须是'M','F'之一", new string[] { "Gender" });
}
if (null == person.Age)
{
yield return new ValidationResult("'Age'是必需字段", new string[] { "Age" });
}
else if (person.Age > || person.Age < )
{
yield return new ValidationResult("'Age'必须在18到25周岁之间", new string[] { "Age" });
}
}
}
四、自定义验证的错误消息
通过在自定义验证特性中重写FormatErrorMessage方法来实现:
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using System.Web.Mvc; namespace MvcValidation.Extension
{
public sealed class EmailAttribute : ValidationAttribute, IClientValidatable
{
public const string reg = @"^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]+$"; public EmailAttribute()
{
} //重写基类方法
public override bool IsValid(object value)
{
if (value == null)
return true; if (value is string)
{
Regex regEx = new Regex(reg);
return regEx.IsMatch(value.ToString());
}
return false;
} public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule rule = new ModelClientValidationRule
{
ValidationType = "email",
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
};
yield return rule;
}
/// <summary>
/// 格式化错误信息
/// </summary>
/// <param name="name">属性名</param>
/// <returns></returns>
public override string FormatErrorMessage(string name)
{ return this.ErrorMessage ?? string.Format("{0}属性没有输入正确的Email", name);
}
}
}
最后,有一些验证还可以用JQuery实现,基本上属于js的东东,这里不再陈述~
本人对MVC验证也只是略懂一二,所以就写这么多吧~
ASP.NET MVC之验证终结者篇的更多相关文章
- 通过扩展改善ASP.NET MVC的验证机制[实现篇]
原文:通过扩展改善ASP.NET MVC的验证机制[实现篇] 在<使用篇>中我们谈到扩展的验证编程方式,并且演示了本解决方案的三大特性:消息提供机制的分离.多语言的支持和多验证规则的支持, ...
- 通过扩展改善ASP.NET MVC的验证机制[使用篇]
原文:通过扩展改善ASP.NET MVC的验证机制[使用篇] ASP.NET MVC提供一种基于元数据的验证方式是我们可以将相应的验证特性应用到作为Model实体的类型或者属性/字段上,但是这依然具有 ...
- ASP.NET MVC Model验证(五)
ASP.NET MVC Model验证(五) 前言 上篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现, 然而在MVC框架中还给我们提供了其它 ...
- ASP.NET MVC Model验证(四)
ASP.NET MVC Model验证(四) 前言 本篇主要讲解ModelValidatorProvider 和ModelValidator两种类型的自定义实现,前者是Model验证提供程序,而Mod ...
- ASP.NET MVC Model验证(三)
ASP.NET MVC Model验证(三) 前言 上篇中说到在MVC框架中默认的Model验证是在哪里验证的,还讲到DefaultModelBinder类型的内部执行的示意图,让大家可以看到默认的M ...
- ASP.NET MVC Model验证(二)
ASP.NET MVC Model验证(二) 前言 上篇内容演示了一个简单的Model验证示例,然后在文中提及到Model验证在MVC框架中默认所处的位置在哪?本篇就是来解决这个问题的,并且会描述一下 ...
- ASP.NET MVC Model验证(一)
ASP.NET MVC Model验证(一) 前言 前面对于Model绑定部分作了大概的介绍,从这章开始就进入Model验证部分了,这个实际上是一个系列的Model的绑定往往都是伴随着验证的.也会在后 ...
- ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)
在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图.但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好.打开Models \ Movie ...
- ASP.NET MVC异步验证是如何工作的03,jquery.validate.unobtrusive.js是如何工作的
在上一篇"ASP.NET MVC异步验证是如何工作的02,异步验证表单元素的创建"中了解了ASP.NET异步验证是如何创建表单元素的,本篇体验jquery.validate.uno ...
随机推荐
- P2831 愤怒的小鸟
P2831 愤怒的小鸟 从 \((0, 0)\) 发射一只鸟, 轨迹满足抛物线, 问最少几只鸟可以打完 \(n <= 18\) 只猪 错误日志: 处理抛物线数组没有初始化 Solution 数据 ...
- P4779 【模板】单源最短路径(标准版)
P4779 [模板]单源最短路径(标准版) 求单源最短路, 输出距离 Solution \(nlogn\) 堆优化 \(Djs\) Code #include<iostream> #inc ...
- Shell记录-Shell命令(文件查找)
常见解压/压缩命令 tar文件格式解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!) .gz文件格式解压1:g ...
- myapplication 单例写法
MyApplication extends Application private static MyApplication myApplication = null; oncreate中: @Ove ...
- 腾讯高级设计师谈微信的旧容与新妆,Android Design是大势所趋
编者按:本篇投稿选自腾讯大讲堂(更多腾讯产品技术文章,可以关注“腾讯大讲堂”微信公众账号),由腾讯研发管理部高级设计师Vertu撰写,他以产品设计师的视角,对比解读了微信的旧容与新妆,也讲了Andro ...
- 基本控件文档-UITextField属性
CHENYILONG Blog 基本控件文档-UITextField属性 Fullscreen UITextField属性技术博客http://www.cnblogs.com/ChenYilong ...
- c++的类型转换(转)
类型转换机制可以分为:隐式类型转换 和 显示类型转换(强制类型转换) C中的类型转换: 事情要从头说起,这个头就是C语言.我们已经习惯了使用C-like类型转换,因为它强大而且简单. 主要有以下两种形 ...
- Django进阶(路由系统、中间件、缓存、Cookie和Session、Ajax发送数据
路由系统 1.每个路由规则对应一个view中的函数 url(r'^index/(\d*)', views.index), url(r'^manage/(?P<name>\w*)/(?P&l ...
- C++ Primer 5th 第18章 用于大型程序的工具
C++大规模程序设计至少存在三个特殊要求: 错误处理 库的引入 复杂建模 以上三种对应C++语言的三种特性:异常处理.命名空间.多重继承. 异常处理 异常处理机制是一种允许偷懒的工具,在出现非正确的情 ...
- gradle 构建工具,与Ant Maven关系
1 基本概念 gradle是一个基于Apache ant 和apache maven概念的项目自动化建构工具.它使用一种基于Groovy的特定领域语言来声明项目设置,而不是传统的xml.当前其支持 ...