MVC之验证
MVC之验证
有时候我觉得,很多人将一个具体的技术细节写的那么复杂,我觉得没有必要,搞得很多人一头雾水的,你能教会别人用就成了,具体的细节可以去查MSDN什么的,套用爱因斯坦的名言:能在网上查到的就不要去记,用的时候拿过来就是。应用层面的东东,没必要深究,真正的核心已经被那些大胡子老外们搞定了,你要说你非想搞明白某个东东,那你可以把你的时间用在架构和管理上去,亦或是你也搞个编译器(搞swift语言的那家伙就是捯饬的这个)什么的,玩玩金融,甚至把把妹子都比你去研究一门最底层的技术细节强,我们常说面向抽象编程,说白了就是低层要依赖高层,所以还是研究点高端的东东对你以后有帮助!
言归正传,MVC验证走起,不过只此一篇,希望能讲多少是多少吧!
一、基于数据注解特性的验证
SO EASY:
A、你如果想用数据注解特性,那就必须要引入以下命名空间:using System.ComponentModel.DataAnnotations;
可以注意到,这个命名空间不是以System.Web开头的,这也说明了它并不单单是为Web项目准备的,如何其它类型的项目都可以使用。
例如:对于一个注册用的model,在其上面用特性验证
using System.ComponentModel.DataAnnotations;
namespace Ctrip.Models
{
public class Register
{
[Required(ErrorMessage="用户名必须填写")]
[MinLength(6,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 {0} 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-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}”,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) == 0))
{
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 > 25 || person.Age < 18)
{
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验证也只是略懂一二,所以就写这么多吧~
MVC之验证的更多相关文章
- 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的绑定往往都是伴随着验证的.也会在后 ...
- MVC 数据验证
MVC 数据验证 前一篇说了MVC数据验证的例子,这次来详细说说各种各样的验证注解.System.ComponentModel.DataAnnotations 一.基础特性 一.Required 必填 ...
- ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)
在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图.但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好.打开Models \ Movie ...
- 【MVC】ASP.NET MVC Forms验证机制
http://www.cnblogs.com/bomo/p/3309766.html 随笔 - 121 文章 - 0 评论 - 92 [MVC]ASP.NET MVC Forms验证机制 ASP. ...
- MVC数据验证原理及自定义ModelValidatorProvider实现无编译修改验证规则和错误信息
Asp.net MVC中的提供非常简单易用的数据验证解决方案. 通过System.ComponentModel.DataAnnotations提供的很多的验证规则(Required, StringLe ...
- MVC 数据验证[转]
前一篇说了MVC数据验证的例子,这次来详细说说各种各样的验证注解. 一.基础特性 一.Required 必填选项,当提交的表单缺少该值就引发验证错误. 二.StringLength 指定允许的长度 指 ...
随机推荐
- 浅析Java中的final关键字(转)
谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法.下 ...
- jdk和cglib简单理解(转)
之前使用cglib的时候不需要将classLoader作为参数传入,但动态代理却要,带着这个疑惑进入这个方法: Proxy.newProxyInstance(classLoader, interfac ...
- 大数据下的数据分析平台架构zz
转自http://www.cnblogs.com/end/archive/2012/02/05/2339152.html 随着互联网.移动互联网和物联网的发展,谁也无法否认,我们已经切实地迎来了一个海 ...
- JavaEE(9) - Session EJB的生命周期、事务及拦截器
1. SessionBean的生命周期 无状态Session Bean: 不存在状态-->待命状态-->被销毁状态 不存在状态-->待命状态: 1)通过构造器创建EJB实例 2)执行 ...
- C++使用简单的函数指针
函数指针: 被调用函数指针必须包括函数的存储器地址,为了正常工作,指针还必须包括其它信息,这一参数列表指针的参数类型和返回类型的函数. 因此,当你声明一个函数指针,数的參数类型和返回类型.以及指针名. ...
- thoughtworks笔试整理
笔试了,时间1个半小时.没想到居然有7/10是开放性问题.大意例如以下:1.为什么选择增加ThoughtWorks.200字以内,不能用"interesting"."ch ...
- 优秀团队建设--美国式团队(ppt)
美国式团队 一.团队精神 团队精神反映一个人的素养.一个人的能力,一个人与别人合作的精神和能力.一个团队是个有机的总体,作为个人,仅仅有全然融入到这个有机总体之中,才干最大限度地体现自己的价值. 团队 ...
- MySQL中游标使用以及读取文本数据
原文:MySQL中游标使用以及读取文本数据 前言 之前一直没有接触数据库的学习,只是本科时候修了一本数据库基本知识的课.当时只对C++感兴趣,天真的认为其它的课都没有用,数据库也是半懂不懂,胡乱就考试 ...
- MVC基本概念和流程
MVC基本概念和流程 MVC的概念 Model(模型):包含数据和行为.不过现在一般都分离开来:Value Object(数据) 和 服务层(行为). View(视图):负责进行模型的展示,一般就是展 ...
- Unity该插件NGUI学习(1)—— 环境结构
Unity官方网站http://unity3d.com/unity/download下载最新版本4.5.4 发现在神圣的论坛裂纹(Windows)版本号http://game.ceeger.com/f ...