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

简介:

对于ASP.NET MVC基于标注特性的Model验证,很多人只知道应用在数据类型及其属性上用于定义验证规则和错误消息的ValidationAttribute。通过《ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidator》的介绍,我们知道了最终用于进行Model验证的是一个叫做ModelValidator的组件。ValidationAttribute对应的ModelValidator为DataAnnotationsModelValidator,这篇简短的文章为你介绍ASP.NET MVC是如何针对Validation来创建DataAnnotationsModelValidator,以及后者如何利用前者实施Model验证的。[本文已经同步到《How ASP.NET MVC Works?》中]

一、DataAnnotationsModelValidator

ModelValidator是真正用于进行Model验证的组件,上面介绍的验证特性最终被封装成DataAnnotationsModelValidator对象进而被应用到Model验证系统中。如下面的代码片断所示,被封装的ValidationAttribute通过只读属性Attribute表示,该属性在构造函数中被初始化。

   1: public class DataAnnotationsModelValidator : ModelValidator
   2: {
   3:     public DataAnnotationsModelValidator(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute);
   4:     public override IEnumerable<ModelClientValidationRule>  GetClientValidationRules();
   5:  
   6:     public override IEnumerable<ModelValidationResult> Validate(object container)
   7:     {
   8:         ValidationContext validationContext = new ValidationContext(container ?? this.Metadata.Model, null, null)
   9:         {
  10:             DisplayName = this.Metadata.GetDisplayName()
  11:         };
  12:         ValidationResult validationResult = this.Attribute.GetValidationResult(this.Metadata.Model, validationContext);
  13:         if (validationResult != ValidationResult.Success)
  14:         {
  15:             ModelValidationResult iteratorVariable2 = new ModelValidationResult
  16:             {
  17:                 Message = validationResult.ErrorMessage
  18:             };
  19:             yield return iteratorVariable2;
  20:         }
  21:         else
  22:         {
  23:             yield break;
  24:         }
  25:     }
  26:     protected ValidationAttribute Attribute { get; }
  27:     protected string ErrorMessage { get; }
  28:     public override bool IsRequired { get; }
  29: }

我们给出了用于实施验证的核心方法Validate的完整定义。在该方法中,基于被验证对象(如果为Null则采用Model元数据的Model属性)创建出表示当前验证上下文的ValidationContext对象,并采用Model元数据的DisplayName属性作为该上下文的显示名称。最后直接调用被封装的ValidationAttribute的GetValidationResult方法对指定对象实施验证,如果返回的ValidationResult对象不为空,则以此创建ModelValidationResult对象并返回。

顺便在说说定义在DataAnnotationsModelValidator中的另外两个受保护只读属性的逻辑。用于返回错误消息的ErrorMessage属性来源对对ValidationAttribute的FormatErrorMessage方法的调用,而指定的参数就是当前Model元数据的DisplayName属性。由于只有RequiredAttribute才用于必需字段的验证,所有只有被封装ValidationAttribute为RequiredAttribute时其IsRequired属性返回True。

二、DataAnnotationsModelValidator<TAttribute>

DataAnnotationsModelValidator<TAttribute>是DataAnnotationsModelValidator的子类,其泛型参数为相应的ValidationAttribute的类型,下面的代码片断反映了其定义:

   1: public class DataAnnotationsModelValidator<TAttribute> : DataAnnotationsModelValidator where TAttribute: ValidationAttribute
   2: {    
   3:     public DataAnnotationsModelValidator(ModelMetadata metadata, ModelBindingExecutionContext context, TAttribute attribute);
   4:     protected TAttribute Attribute { get; }
   5: }

作为DataAnnotationsModelValidator与相应ValidationAttribute之间的适配,ASP.NET MVC为常用的ValidationAttribute(RequiredAttribute、RangeAttribute、RegularExpressionAttribute和StringLengthAttribute)定义相应的适配类型。如下面的代码片断所示,它们都是泛型的DataAnnotationsModelValidator<TAttribute>的子类。当我们将这些ValidationAttribute应用到Model类型时,真正用于Model验证的实际上就是这些作为适配的ModelValidator。

   1: public class RequiredAttributeAdapter : DataAnnotationsModelValidator<RequiredAttribute>
   2: {
   3:     public RequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute);
   4:     public override IEnumerable<ModelClientValidationRule> GetClientValidationRules();
   5: }
   6:  
   7: public class RangeAttributeAdapter : DataAnnotationsModelValidator<RangeAttribute>
   8: {    
   9:     public RangeAttributeAdapter(ModelMetadata metadata, ControllerContext context, RangeAttribute attribute);
  10:     public override IEnumerable<ModelClientValidationRule> GetClientValidationRules();
  11: }
  12:  
  13: public class RegularExpressionAttributeAdapter : DataAnnotationsModelValidator<RegularExpressionAttribute>
  14: {    
  15:     public RegularExpressionAttributeAdapter(ModelMetadata metadata, ControllerContext context, RegularExpressionAttribute attribute);
  16:     public override IEnumerable<ModelClientValidationRule> GetClientValidationRules();
  17: }
  18:  
  19: public class StringLengthAttributeAdapter : DataAnnotationsModelValidator<StringLengthAttribute>
  20: {    
  21:     public StringLengthAttributeAdapter(ModelMetadata metadata, ControllerContext context, StringLengthAttribute attribute);
  22:     public override IEnumerable<ModelClientValidationRule>GetClientValidationRules();
  23: }

 

ASP.NET MVC基于标注特性的Model验证:ValidationAttribute
ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidator
ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidatorProvider
ASP.NET MVC基于标注特性的Model验证:将ValidationAttribute应用到参数上
ASP.NET MVC基于标注特性的Model验证:一个Model,多种验证规则


作者:蒋金楠
微信公众账号:大内老A
微博: www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号 蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
相关文章
|
9月前
|
开发框架 .NET API
.NET 10首个预览版发布:重大改进与新特性概览!
.NET 10首个预览版发布:重大改进与新特性概览!
299 3
.NET 10首个预览版发布:重大改进与新特性概览!
|
人工智能 开发框架 .NET
.NET技术的强大功能:.NET技术的基础特性、在现代开发中的应用、以及它如何助力未来的软件开发。
.NET技术是软件开发领域的核心支柱,以其强大功能、灵活性及安全性广受认可。本文分三部分解析:基础特性如多语言支持、统一运行时环境;现代应用如企业级与Web开发、移动应用、云服务及游戏开发;以及未来趋势如性能优化、容器化、AI集成等,展望.NET在不断变化的技术环境中持续发展与创新。
485 4
|
8月前
|
前端开发 IDE Java
Spring MVC 中因导入错误的 Model 类报错问题解析
在 Spring MVC 或 Spring Boot 开发中,若导入错误的 `Model` 类(如 `ch.qos.logback.core.model.Model`),会导致无法解析 `addAttribute` 方法的错误。正确类应为 `org.springframework.ui.Model`。此问题通常因 IDE 自动导入错误类引起。解决方法包括:删除错误导入、添加正确包路径、验证依赖及清理缓存。确保代码中正确使用 Spring 提供的 `Model` 接口以实现前后端数据传递。
255 0
|
10月前
|
人工智能 机器人
D1net阅闻 | 谷歌DeepMind研究发现LLM新特性
D1net阅闻 | 谷歌DeepMind研究发现LLM新特性
|
自然语言处理 物联网 图形学
.NET 技术凭借其独特的优势和特性,为开发者们提供了一种高效、可靠且富有创造力的开发体验
本文深入探讨了.NET技术的独特优势及其在多个领域的应用,包括企业级应用、Web应用、桌面应用、移动应用和游戏开发。通过强大的工具集、高效的代码管理、跨平台支持及稳定的性能,.NET为开发者提供了高效、可靠的开发体验,并面对技术更新和竞争压力,不断创新发展。
611 7
|
开发框架 .NET C#
.NET 技术凭借高效开发环境、强大框架支持及跨平台特性,在软件开发中占据重要地位
.NET 技术凭借高效开发环境、强大框架支持及跨平台特性,在软件开发中占据重要地位。从企业应用到电子商务,再到移动开发,.NET 均展现出卓越性能,助力开发者提升效率与项目质量,推动行业持续发展。
328 4
|
JSON C# 开发者
C#语言新特性深度剖析:提升你的.NET开发效率
【10月更文挑战第15天】C#语言凭借其强大的功能和易用性深受开发者喜爱。随着.NET平台的演进,C#不断引入新特性,如C# 7.0的模式匹配和C# 8.0的异步流,显著提升了开发效率和代码可维护性。本文将深入探讨这些新特性,助力开发者在.NET开发中更高效地利用它们。
208 1
|
存储 编译器
.Net特性Attribute的高级使用
【10月更文挑战第14天】在.NET中,特性(Attribute)是一种强大的机制,用于在代码中添加元数据。本文介绍了特性的高级用法,包括自定义特性、通过反射读取特性、条件编译与特性结合、多个特性应用以及特性继承。通过示例展示了如何创建自定义特性类、应用自定义特性,并通过反射获取特性信息。此外,还介绍了如何利用条件编译符号实现不同版本的代码控制,以及如何在一个代码元素上应用多个特性。最后,探讨了如何通过`AttributeUsage`控制特性的继承行为。
280 1
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
232 7
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
268 0