原文:asp.net mvc3 数据验证(三)—自定义数据注解

        前两节讲的都是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<ValidationResult> 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,下载请点击:http://pan.baidu.com/share/link?shareid=143863&uk=4044128861

asp.net mvc3 数据验证(三)—自定义数据注解的更多相关文章

  1. ASP.NET MVC Model验证(三)

    ASP.NET MVC Model验证(三) 前言 上篇中说到在MVC框架中默认的Model验证是在哪里验证的,还讲到DefaultModelBinder类型的内部执行的示意图,让大家可以看到默认的M ...

  2. atitit.数据验证--db数据库数据验证约束

    atitit.数据验证--db数据库数据验证约束 1. 为了加强账户数据金额的安全性,需要增加验证字段..1 2. 创建帐户1 3. 更改账户2 4. ---code3 5. --fini4 1. 为 ...

  3. MySQL行(记录)的详细操作一 介绍 二 插入数据INSERT 三 更新数据UPDATE 四 删除数据DELETE 五 查询数据SELECT 六 权限管理

    MySQL行(记录)的详细操作 阅读目录 一 介绍 二 插入数据INSERT 三 更新数据UPDATE 四 删除数据DELETE 五 查询数据SELECT 六 权限管理 一 介绍 MySQL数据操作: ...

  4. ASP.NET MVC3 Model验证总结 @Html.ValidationSummary(true)

    http://www.wyjexplorer.cn/Post/2012/8/3/model-validation-in-aspnet-mvc3 ASP.NET MVC3中的Model是自验证的,这是通 ...

  5. 我这么玩Web Api(二):数据验证,全局数据验证与单元测试

    目录 一.模型状态 - ModelState 二.数据注解 - Data Annotations 三.自定义数据注解 四.全局数据验证 五.单元测试   一.模型状态 - ModelState 我理解 ...

  6. ASP.NET MVC3 Model验证总结

    ASP.NET MVC3中的Model是自验证的,这是通过.NET4的System.ComponentModel.DataAnnotations命名空间完成的. 我们要做的只是给Model类的各属性加 ...

  7. ASP.NET MVC3 Model验证总结(转)

    推荐:   ASP.NET MVC的Model元数据与Model模板:预定义模板 http://www.cnblogs.com/artech/archive/2012/05/02/model-meta ...

  8. 转:ASP.NET MVC3 Model验证总结

    http://www.wyjexplorer.cn/Post/2012/8/3/model-validation-in-aspnet-mvc3 ASP.NET MVC3中的Model是自验证的,这是通 ...

  9. 在ASP.NET MVC3项目中,自定义404错误页面

    在Web开发中,用户体验是至关重要的,一个友好的网站自然少不了自定义404错误页面. 让笔者为大家介绍404错误页面在ASP.NET MVC3项目中的配置: 第一步,在项目的Web.config文件中 ...

  10. vue.js实战——props数据验证(自定义构造器检测)

    Vue.component('my-component',{ props:{ //必须是数字类型 propA:Number, //必须是字符串或数字类型 propB:[String,Number], ...

随机推荐

  1. 思维导图(自己整理,希望对大家有用):JavaScript函数+canvas绘图+Array数组

    1.javascript函数: 2.Array数组: 3.canvas绘图:

  2. RH253读书笔记(4)-Lab 4 The Domain Name System

    Lab 4 The Domain Name System Goal: To install and configure a DNS server System Setup: Throughout th ...

  3. js便签笔记(13)——jsonp事实上非常easy【ajax跨域请求】

    前两天被问到ajax跨域怎样解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来.抱着有问题必须解决的态度,我看了很多资料,原来如此.. . 为何一直知道jsonp,但一直迷迷糊糊的不明 ...

  4. state-of-the-art implementations related to visual recognition and search

    http://rogerioferis.com/VisualRecognitionAndSearch2014/Resources.html Source Code Non-exhaustive lis ...

  5. MEF初体验之十一:查询组合容器

    查询组合容器 组合容器暴露了几个get exports的重载方法和导出对象和对象集合.你需要注意下面的行为: 当请求单个对象实例时,如果未发现导出,一个异常将被抛出 当请求单个对象实例时,如果发现超过 ...

  6. SQL Server 2008 R2 性能计数器详细列表(五)

    原文:SQL Server 2008 R2 性能计数器详细列表(五) SQL Server:SQL Statistics 对象: 监视编译和发送到 SQL Server 实例的请求类型 SQL Ser ...

  7. folat i = 0.1; 警告

    今天的用途  float i = 0.1;那么编译器警告实际: #include <iostream> using namespace std; int main() { float k ...

  8. UVa 10285 - Longest Run on a Snowboard

    称号:给你一个二维矩阵,找到一个点.每一个可以移动到的位置相邻的上下,求最长单调路径. 分析:贪婪,dp.搜索. 这个问题是一个小样本,我们该怎么办. 这里使用贪心算法: 首先.将全部点依照权值排序( ...

  9. 创建Windows类别

    Windows在表单.控制.对话框基本上形成.Windows类是Windows形式的类型,可处理叙述性说明. 在Windows提前有很多定义Windows类别,但它可以很容易地创建自己的Windows ...

  10. 【安德鲁斯】于java代码集drawableLeft给予适当的大小如何,当?

    textView.setCompoundDrawables(drawable, null, null, null);如果看不到图片,这是由于需要手动定drawable适当的大小,使用drawable. ...