注:本节阅读需要有MVC 自定义验证的基础,否则比较吃力
一直以来表单的验证都是不可或缺的,微软的东西还是做得比较人性化的,从webform到MVC,都做到了双向验证
单单的用js实现的前端验证是极其不安全的,所以本次我们来看看MVC上的自带的注解验证,自定义验证
同样的MVC提供了一系列内置的数据验证注解
- 不为空验证 [Required(ErrorMessage = "不能为空")]
- 长度验证 [StringLength(10, MinimumLength = 2)]
- 取值范围 [Range(1, 3)]
- 类型验证 [DataType(DataType.Date)]
- 正则表达 [RegularExpression(@”[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+/.[A-Za-z]{2,4}”)] Email Demo
- 远程验证 [Remote("CheckUserNameExists", "ValidationDemo", ErrorMessage = "用户名已存在")]
- 请求验证 [AllowHtml] 允许传入HTML
- 等等.....
MVC3项目模板自带的登录模型类如下:
public class LogOnModel { [Required] [Display(Name = "User name")] public string UserName { get; set; } [Required] [DataType(DataType.Password)] [Display(Name = "Password")] public string Password { get; set; } [Display(Name = "Remember me?")] public bool RememberMe { get; set; } }
MVC3自带的模板项目中已经有了:
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
然后在被验证的View页面上要参加如许两个JavaScript,重视,他们是依附于JQuery的:
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
验证消息的显示有两种,一种是ValidationSummary,它可以显示一份验证消息的汇总,包含从后台Action里返回的消息。
@Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.")
另一种是Model中各属性对应HTML控件的验证消息:
@Html.ValidationMessageFor(m => m.UserName)
所以要前端代码有验证效果必须引入jquery库
但是往往系统自带的验证是远远满足不了我们的,我们需要更加灵活的封装,不可能我要验证数字是否填了 0-9之间都要去写一个表表达式吧,还好官方也灵活的提供了扩展,自定义验证。
自定义验证我就不多说了,在园里搜索一下就很多原理及编写方法。这里我为大家共享一个常用的自定验证

双向验证引入JS,否则无法启用前端验证

一共包含了19个常用验证及封装
* 1. [IntRangeExpression(18, 30)] 数字在18与30之间,可以不填写,但填写就进入验证
* 2. [MaxWordsExpression(50)] 字符数在不能大50,可以不填写,但填写就进入验证
* 3. [NotNullExpression] 验证是否为空且 调用
* 4. [DateExpression] 是否是日期格式:2012-10-1
* 5. [IsCharExpression] 只能是数字,字母,下划线,中划线组成,可以不填写
* 6. [ChinaCharExpression] 只能输入汉字,可以不填写
* 7. [NotEqualExpression("abcd")] 不能等于指定的值,可以不填写:如不能等于abcd
* 8. [ContainExpression("abc")] 验证是否包含指定字符串,可以不填写:如必须包含abc
* 9. [NotContainExpression("abc")] 验证不能指定字符串,可以不填写,如不能含有abc
*10. [IsIntegerEpression] 验证是否是数字格式 可以不填写,可以为任意整数 1,-5
*11. [IsPositiveIntegerExpression] 验证是否是数字格式,可以不填写,必须是任意正整数 25
*12. [IsNegativeIntegerExpression] 验证是否是数字格式,可以不填写,必须是任意负整数 -25
*13. [IsDecimalExpression] 验证是否是数字格式 可以不填写,可以为任意浮点数 12.12,12,-12.12
*14. [IsPositiveDecimalExpression] 验证是否是数字格式 可以不填写,可以为任意正浮点数 1.4
*15. [IsNegativeDecimalExpression] 验证是否是数字格式 可以不填写,可以为任意负浮点数 -1.2
*16. [EmailExpression] 验证是否是Email
*17. [PhoneExpression] 验证是否是中国电话号码 如:0769-222222-222 正确格式为:"XXX-XXXXXXX"、"XXXX- XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"。
*18. [SiteExpression] 验证是否是一个完整的网址 如:www.163.com
*19. [IsNumberExpression] 验证是否是数字格式 可以不填写,可以为任意数字
使用方法
* 组合使用演示
* [DisplayName("姓名")] 名称
* [NotNullExpression] 不能为空
* [MaxWordsExpression(50)] 最多50个字符,25个汉字
* [IsCharExpression] 只能由数字,字母,中划线,下划线组成(一般用于验证ID)
* [NotEqualExpression("admin")] 不能包含有admin字符串
* public string Id { get; set; }
*
* 数字判断演示
* [IsNumberExpression] 可以不填写,填写判断是否是数字
* [DisplayName("代号")]
* public int? age { get; set; }
* 非空字断使用
* //[Required(ErrorMessageResourceType = typeof(ErrorRs), ErrorMessageResourceName = "IsNumberExpression")]
* 或//[Required(ErrorMessage="必须填写这个字段")] 来覆盖本地化 如public int age; int?为可空字端
摘一段代码解释一下吧 比如这个[NotNullExpression] 方法
public class NotNullExpressionAttribute : ValidationAttribute, IClientValidatable { static string DispalyName = ""; public NotNullExpressionAttribute() : base("{0}必须填写") { } public override string FormatErrorMessage(string name) { return String.Format(name, DispalyName); } public override bool IsValid(object value) { if (value == null) { return false; } string valueAsString = value.ToString(); bool result = !string.IsNullOrEmpty(valueAsString); return result; } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { DispalyName = metadata.DisplayName; return new[]{ new ModelClientValidationRequiredRule(FormatErrorMessage("{0}必须填写")) }; } }
校验的方法 IsValid
客户端的验证规则 GetClientValidationRules
封装的错误信息 : base("{0}必须填写") 0代表的是displayName
其他方法都是类似的做法,大家可以根据自己的需要扩展验证。
我们来看看在实际项目中的应用吧!!
//------------------------------------------------------------------------------ // <auto-generated> // 此代码由T4模板自动生成 // 生成时间 2013-03-12 16:05:27 by App // 对此文件的更改可能会导致不正确的行为,并且如果 // 重新生成代码,这些更改将会丢失。 // </auto-generated> //------------------------------------------------------------------------------ using System; using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; namespace App.Models.Sys { [DataContract] public class SysSampleModel { [Display(Name = "ID")] public string Id { get; set; } [NotNullExpression] [Display(Name = "名称")] public string Name { get; set; } [Display(Name = "年龄")] [Range(0,10000)] public int? Age { get; set; } [Display(Name = "生日")] public DateTime? Bir { get; set; } [MaxLength(5)] [Display(Name = "照片")] [Required] public string Photo { get; set; } [MinLength(5)] [Display(Name = "简介")] public string Note { get; set; } [DateExpressionAttribute] [Display(Name = "创建时间")] public DateTime? CreateTime { get; set; } } }
在model中使用了[NotNullExpression] 与[DateExpressionAttribute]日期验证
打开我们的代码生成器生成SysSample的Create视图,前提你已经创建自定义验证的类和在Create引入验证规则。
之前有关于系列的朋友都有这个样例。如果没有关注的,你可以自己创建一个普通的。
代码生成器生成以下代码:

预览效果
前端如果判断和自动输出错误的关键代码在$("form").valid() 这里
后台的关键判断代码在if (model != null && ModelState.IsValid)
只有都为true时才通过双向验证,有力保证系统数据库的安全
总结:其实极其简单的演示,我们创建的MVC3项目中实例已经可以看出来,然而我们封装的验证有效的重用于项目之间
如果你有过硬的正则表达式基础,你完全可以写出更多符合系统的表单验证
这里我只是共享我写的一个验证类,可以直接使用与项目中,配合生成器生成规则验证,其他特性还待园友自行摸索了。
本文转自ymnets博客园博客,原文链接:http://www.cnblogs.com/ymnets/p/3635888.html,如需转载请自行联系原作者