博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
asp.net mvc3 数据验证(三)—自定义数据注解
阅读量:4921 次
发布时间:2019-06-11

本文共 3809 字,大约阅读时间需要 12 分钟。

        前两节讲的都是asp.net mvc3预先设定的数据注解,但是系统自由的数据注解肯定不适合所有的场合,所以有时候我们需要自定义数据注解。
        自定义数据注解有两种,一种是直接写在模型对象中,这样做的好处是验证时只需要关心一种模型对象的验证逻辑,缺点也是显而易见的,那就是不能重用。
                                            还有一种是封装在自定义的数据注解中,优点是可重用,缺点是需要应对不同类型的模型。
        现在我们以封装在自定义数据注解中的方法为例看下如何在asp.net mvc3中自定义数据注解以及使用。
 
一、自定义属性级别的验证
        首先,所有的数据注解都应继承于 System.ComponentModel.DataAnnotations命名空间中的 ValidationAttribute类。
            重写其 protected virtual ValidationResult IsValid(object value, ValidationContext validationContext);
例如:
        我们需要写一个UserName不能超过10个字母的数据注解(你可能会说这不是有的 StringLength么,好吧,仅以此为例,我真没想到其他的需要自定义数据注解的好例子)。
        (1)新建一个类 MaxLengthAttribute,代码如下:
public class MyMaxLengthAttribute : ValidationAttribute    {        private readonly int MaxLength;         public MyMaxLengthAttribute(int maxLength)        {            MaxLength = maxLength;        }         protected override ValidationResult IsValid(object value, ValidationContext validationContext)        {            string content = value.ToString();            if (content.Length > MaxLength)            {                return new ValidationResult("输入的字符太多了!^_^");            }            return ValidationResult.Success;            //return base.IsValid(value, validationContext);        }
        第二步就是像正常使用asp.net自带的数据注解一样使用,如:
        
[Required(ErrorMessageResourceType=typeof(ErrorMessage),ErrorMessageResourceName="UserRequire")]        [Display(Name = "用户名")]        [MyMaxLengthAttribute(10)]        [Remote("CheckUserName","Account", HttpMethod="POST")]        public string UserName { get; set; }
        好了,只需要这样简单的两步就可以实现了。

验证结果:
        对于自定义的数据注解由于是继承于 System.ComponentModel.DataAnnotations命名空间中的 ValidationAttribute类,所以它的一些属性也可以使用,比如ErrorMessage,如:
[Required(ErrorMessageResourceType=typeof(ErrorMessage),ErrorMessageResourceName="UserRequire")]        [Display(Name = "用户名")]        [MyMaxLengthAttribute(10,ErrorMessage="{0}字数太多")]        [Remote("CheckUserName","Account", HttpMethod="POST")]        public string UserName { get; set; }
        需要注意的是,自定义的数据注解不支持客户端验证,所有的数据需要提交之后再服务端验证,所以如果要同时实现客户端验证需要自己写js验证。
 
但是这样的验证有一个问题,就是默认的验证信息不能实现直接显示Display Name,所以需要如下更改:
public class MyMaxLengthAttribute : ValidationAttribute    {        private readonly int MaxLength;         public MyMaxLengthAttribute(int maxLength ):base("{0}的字符太多了!")        {            MaxLength = maxLength;        }         protected override ValidationResult IsValid(object value, ValidationContext validationContext)        {            string content = value.ToString();            if (content.Length > MaxLength)            {                //return new ValidationResult("输入的字符太多了!^_^");                string errorMessage = FormatErrorMessage(validationContext.DisplayName);                 return new ValidationResult(errorMessage);            }            return ValidationResult.Success;            //return base.IsValid(value, validationContext);        }    }
 
 验证结果:

 
二、自定义Model级别的验证(IValidatableObject)
        这个接口是为了实现Model的自验证(self-validating)的,是asp.net mvc3 新增的验证特性。这个特性和普通数据注解的区别是普通数据注解仅仅只能验证Model的一个属性,而实现了IValidatableObject接口的自验证则在Model的级别来验证,比如验证Model的几个属性之间的关系等。
        例如,我要验证两次输入的密码相同(好吧,我又把系统自带的验证再写一遍)。
        (1)首先,要将需要验证的Model实现IValidatableObject接口。
     public class RegisterModel : IValidatableObject
        (2)在Model中实现 Validate方法:
public IEnumerable
Validate(ValidationContext validationContent) { if (Password != ConfirmPassword) { yield return new ValidationResult("两次输入的密码不同!", new[] { "Password" }); } }

 

        这个方法在提交Model时会自动验证两次输入的密码是否相同,如果不同则会提示,如下:

 
注意:1、自验证只能把方法写在需要验证的Model中,所以这种自验证的代码无法重用;
            2、自验证的返回值是
IEnumerable<ValidationResult>,而不是
ValidationResult,所以返回值可以不止一个验证错误。
            3、Validate方法没有传入value参数,也就是意味着Validate方法可以直接访问Model中的属性值。
            4、返回值使用的是yield return来构建枚举返回值,第二个参数是指定错误信息绑定的属性,因为是string数组,所以可以关联多个属性。
 
顺便把练习用的源码分享了,Model部分主要在RegisterModel,下载请点击:

转载于:https://www.cnblogs.com/zhangkai2237/archive/2012/12/12/2814825.html

你可能感兴趣的文章
vim部分常用命令总结
查看>>
TensorFlow TensorBoard使用
查看>>
快速傅里叶变换(FFT)蝴蝶迭代
查看>>
【解题报告】BSOI2550 方格取数游戏 (转)
查看>>
为IEnumerable扩展一个ForEach方法
查看>>
面试题6:重建二叉树(前序遍历和中序遍历)
查看>>
(六)Oracle学习笔记—— 约束
查看>>
Node.js相关——CommonJS规范
查看>>
知交好友剩几个
查看>>
画图演示方法的执行过程
查看>>
Python列表切成多个/生成多个空列表
查看>>
Web前端性能优化
查看>>
根文件系统的制作
查看>>
最短路径算法----floyd(转)
查看>>
资源 | 普通程序员如何自学机器学习
查看>>
用R自动生成pdf文件
查看>>
运行时错误'430': 类不支持自动化或不支持期望的接口。New ADODB.Connection问题...
查看>>
mysql 查找树状子节点函数
查看>>
tp查询中2个表格中字段,比较大小
查看>>
课堂练习之找出所有的“1”
查看>>