ASP.NET MVC基于标注特性的Model验证:ValidationAttribute

通过前面的介绍我们知道ModelValidatorProviders的静态只读Providers维护着一个全局的ModelValidatorProvider列表,最终用于Model验证的ModelValidator都是通过这些ModelValidatorProvider来提供的。对于该列表默认包含的三种ModelValidatorProvider来说,DataAnnotationsModelValidatorProvider无疑是最重要的,ASP.NET MVC默认提供的基于数据标注特性的声明式Model验证就是通过DataAnnotationsModelValidatorProvider提供的DataAnnotationsModelValidator来实现的。

一、ValidationAttribute特性

与通过数据标注特性定义Model元数据类似,我们可以在作为Model的数据类型及其属性上应用相应的标注特性来定义Model验证规则。所有的验证特性都直接或者间接继承自抽象类型System.ComponentModel.DataAnnotations.ValidationAttribute。如下面的代码片断所示,ValidationAttribute具有一个字符串类型的ErrorMessage属性用于指定验证错误消息。出于对本地化或者对错误消息单独维护的需要,我们可以采用资源文件的方式来保存错误消息,在这种情况下我们只需要通过ErrorMessageResourceName和ErrorMessageResourceType这两个属性指定错误消息所在资源项的名称和类型即可。

   1: public abstract class ValidationAttribute : Attribute   2: {   3:     public string ErrorMessage { get; set; }   4:     public string ErrorMessageResourceName { get; set; }   5:     public Type ErrorMessageResourceType { get; set; }   6:     protected string ErrorMessageString {get;}   7:   8:     public virtual string FormatErrorMessage(string name);   9:  10:     public virtual bool IsValid(object value);  11:     protected virtual ValidationResult IsValid(object value, ValidationContext validationContext)  12:  13:     public void Validate(object value, string name);  14:     public ValidationResult GetValidationResult(object value, ValidationContext validationContext);  15: }

二、验证消息的定义

如果我们通过ErrorMessage属性指定一个字符串作为验证错误消息,又通过ErrorMessageResourceName/ErrorMessageResourceType属性指定了错误消息资源项对应的名称和类型,后者具有更高的优先级。ValidationAttribute具有一个受保护的只读属性ErrorMessageString用于返回最终的错误消息文本。

对于错误消息的定义,我们可以定义一个完整的消息,比如“年龄必需在18至25之间”。但是对于像资源文件这种对错误消息进行独立维护的情况,为了让定义的资源文本能够最大限度地被重用,我们倾向于定义一个包含占位符的文本模板,比如“{DisplayName}必需在{LowerBound}和{UpperBound}之间”,这样消息适用于所有基于数值范围的验证。对于后者,模板中的占位符可以在虚方法FormatErrorMessage中进行替换。该方法中的参数name实际上代表的是对应的显示名称,即对应ModelMetadata的DisplayName属性。

FormatErrorMessage方法在ValidationAttribute中的默认实现仅仅是简单地调用String的静态方法Format将参数name作为替换占位符的参数,具体的定义如下。所以在默认的情况下,我们在定义错误消息模板的时候,只允许包含唯一一个针对显示名称的占位符“{0}”。如果具有额外的占位符,或者不需要采用基于序号(“{0}”)的定义方法(比如采用类似于“{DisplayName}”这种基于文字的占位符更具可读性),只需要重写FormatErrorMessage方法即可。

   1: public abstract class ValidationAttribute : Attribute   2: {   3:     //其他成员   4:     public virtual string FormatErrorMessage(string name)   5:     {   6:         return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, new object[] { name });   7:     }   8: }

三、验证的执行

当我们通过继承ValidationAttribute创建我们自己的验证特性的时候,可以通过重写公有方法IsValid或者受保护方法IsValid来实现我们自定义的验证逻辑。我们之所以能够通过重写任一个IsValid方法是我们自定义验证逻辑生效的原因在于这两个方法在ValidationAttribute特殊的定义方法。按照这两个方法在ValidationAttribute中的定义,它们之间存在相互调用的关系,而这种相互调用必然造成“死循环”,所以我们需要重写至少其中一个方法比避免“死循环”的方法。这里的“死循环”被加上的引号,是因为ValidationAttribute在内部作了处理,当这种情况出现的时候会抛出一个NotImplementedException异常。

   1: //调用公有IsValid方法   2: public class ValidatorAttribute : ValidationAttribute   3: {   4:     static void Main()   5:     {   6:         ValidatorAttribute validator = new ValidatorAttribute();   7:         validator.IsValid(new object());   8:     }   9: }  10:  11: //调用受保护IsValid方法  12: public class ValidatorAttribute : ValidationAttribute  13: {  14:     static void Main()  15:     {  16:         ValidatorAttribute validator = new ValidatorAttribute();  17:         validator.IsValid(new object(),null);  18:     }  19: }

为了验证对虚方法IsValid重写的必要性,我们来做一个简单的实例演示。在一个控制台应用中我们分别编写了如上两段程序,其中通过继承ValidationAttribute定义了一个ValidatorAttribute,但是没有重写任何一个IsValid方法。当我们在Debug模式下分别运行这两段程序的时候,都会抛出如下图所示的NotImplementedException异常,提示“此类尚未实现 IsValid(object value)。首选入口点是 GetValidationResult(),并且类应重写 IsValid(object value, ValidationContext context)。”

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索验证
, 方法
, 调用自定义资源
, 消息
, public
, ValidationAttribute
, 一个
MVC自定义错误
,以便于您获取更多的相关知识。

时间: 2024-10-29 01:32:44

ASP.NET MVC基于标注特性的Model验证:ValidationAttribute的相关文章

ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidator

对于ASP.NET MVC基于标注特性的Model验证,很多人只知道应用在数据类型及其属性上用于定义验证规则和错误消息的ValidationAttribute.通过<ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidator>的介绍,我们知道了最终用于进行Model验证的是一个叫做ModelValidator的组件.ValidationAttribute对应的ModelValidator为DataAnnotationsModelValidat

ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidatorProvider

DataAnnotationsModelValidator最终是通过它对应的ModelValidatorProvider,即DataAnnotationsModelValidatorProvider创建的.通过前面的介绍我们知道它是AssociatedValidatorProvider的子类,后者在用于获取ModelValidator的GetValidators方法中已经根据指定的Model元数据所有特性创建出来,DataAnnotationsModelValidator只需要从中筛选出继承自V

ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上

ASP.NET MVC默认采用基于标准特性的Model验证机制,但是只有应用在Model类型及其属性上的ValidationAttribute才有效.如果我们能够将ValidationAttribute特性直接应用到参数上,我们不但可以实现简单类型(比如int.double等)数据的Model验证,还能够实现"一个Model类型,多种验证规则",本篇文章将为你提供相关的解决方案(源代码从这里下载). 一.ValidationAttribute本身是可以应用到参数上的 如果你够细心应该会

ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则

对于Model验证,理想的设计应该是场景驱动的,而不是Model(类型)驱动的,也就是对于同一个Model对象,在不同的使用场景中可能具有不同的验证规则.举个简单的例子,对于一个表示应聘者的数据对象来说,针对应聘的岗位不同,肯定对应聘者的年龄.性别.专业技能等方面有不同的要求.但是ASP.NET MVC的Model验证确是Model驱动的,因为验证规则以验证特性的形式应用到Model类型及其属性上.这样的验证方式实际上限制了Model类型在基于不同验证规则的使用场景中的重用.通过上一篇文章<将V

ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidatorProvider

DataAnnotationsModelValidator最终是通过它对应的ModelValidatorProvider,即DataAnnotationsModelValidatorProvider创建的.通过前面的介绍我们知道它是AssociatedValidatorProvider的子类,后者在用于获取ModelValidator的GetValidators方法中已经根据指定的Model元数据所有特性创建出来,DataAnnotationsModelValidator只需要从中筛选出继承自V

[ASP.NET MVC]如何定制Numeric属性/字段验证消息

对于一个Numeric属性/字段,ASP.NET MVC会自动进行数据类型的验证(客户端验证),以确保输入的是一个有效的数字,但是呈现在页面上的错误消息总是一段固定的文本:"The field {0} must be a number",本篇提供一种解决方案使我们可以对此验证消息进行定制.[源代码从这里下载] 目录 一.针对Numeric属性/字段默认验证消息 二.默认的验证消息来源于何处? 三.通过自定义ModelValidatorProvider替换NumericModelVali

【译】ASP.NET MVC 5 教程 - 10:添加验证

原文:[译]ASP.NET MVC 5 教程 - 10:添加验证 在本节中,我们将为Movie模型添加验证逻辑,并确认验证规则在用户试图使用程序创建和编辑电影时有效. DRY 原则 ASP.NET MVC 的一个核心原则是DRY(Don't Repeat Yourself - 不做重复的事情).ASP.NET MVC 鼓励你一次性的指定功能或行为,然后应用程序的其它地方通过映射得到它,这样一来就减少了大量的代码,从而减少了出错误的可能性,并且更易于维护. ASP.NET  MVC  和 Enti

ASP.NET MVC 5 学习教程:添加验证

原文 ASP.NET MVC 5 学习教程:添加验证 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 通过控制器访问模型的数据 生成的代码详解 使用 SQL Server LocalDB Edit方法和Edit视图详解 添加查询 Entity Framework 数据迁移之添加字段 添加验证 Details 和 Delete 方法详解 在本节中,我们将为Movie模型添加验证逻辑,并确认验证规则在用户试图

支持ASP.NET MVC、WebFroM的表单验证框架ValidationSuar使用介绍

  这篇文章主要介绍了支持ASP.NET MVC.WebFroM的表单验证框架ValidationSuar使用介绍,本文详细讲解了使用步骤,并给出一个完整Demo下载,需要的朋友可以参考下 1.支持javascript端和后端的双重验证 (前端目前依赖于jquery.validate.js,也可以自已扩展) 2.代码简洁 3.调用方便 4.功能齐全 使用方法: 新建初始化类,将所有需要验证的在该类进行初始化,语法相当简洁并且可以统一管理,写完这个类你的验证就完成了70% 函数介绍: Add 默认