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 指定允许的长度 指 ...
随机推荐
- matlab简单实现SVD的推荐
%svd chengxu A = [5 5 0 5;5 0 3 4; 3 4 0 3; 0 0 5 3; 5 4 4 5; 5 4 5 5]; A = A'; [U S V] = svd(A); U ...
- 离robots.txt启动网络爬虫之旅
要成为一个网络爬虫或搜索引擎(在这里,共同蜘蛛)它不会陌生,在搜索引擎爬虫的第一个文件或者访问该网站上浏览robots.txt该.robots.txt文件讲述了蜘蛛server哪些文件要观看正在. 当 ...
- springMVC+angular+bootstrap+mysql的简易购物网站搭建
springMVC+angular+bootstrap+mysql的简易购物网站搭建 介绍 前端的css框架用了bootstrap, 以及bootstrap的JS组件, 以及很好用的angular(a ...
- 类(class)能不能自己继承自己(转)
类(class)能不能自己继承自己不行,继承关系会出现环. 假设类A继承类A.那么要新建一个类A的对象,就必须先建立一个类A父类的对象.这是一个递归的过程,而且没有终止条件.会死循环的. 从编译的角度 ...
- SpringMVC传参
@Controller @RequestMapping("/user") public UserController extends BaseController{ @InitBi ...
- React实践
React实践(一) 该实践取自官方教程:https://github.com/reactjs/react-tutorial 主要是自实现的过程以及一些心得体会 该实践是实现一个评论框. 一个展示 ...
- spark(1.1) mllib 源代码分析
在spark mllib 1.1加入版本stat包,其中包括一些统计数据有关的功能.本文分析中卡方检验和实施的主要原则: 一个.根本 在stat包实现Pierxunka方检验,它包括以下类别 (1)适 ...
- SettingsProvider该CRUD
转载请注明出处:http://blog.csdn.net/droyon/article/details/35558697 什么时候delete要么update时间.需要清空缓存并重新加载数据. 1.i ...
- Swift语言指南(一)--语言基础之常量和变量
原文:Swift语言指南(一)--语言基础之常量和变量 Swift 是开发 iOS 及 OS X 应用的一门新编程语言,然而,它的开发体验与 C 或 Objective-C 有很多相似之处. Swif ...
- my97 日期控件
官网:http://www.my97.net/ 好多广告啊! 文档地址: http://www.mysuc.com/test/My97DatePicker/