ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidatorProvider
DataAnnotationsModelValidator最终是通过它对应的ModelValidatorProvider,即DataAnnotationsModelValidatorProvider创建的。通过前面的介绍我们知道它是AssociatedValidatorProvider的子类,后者在用于获取ModelValidator的GetValidators方法中已经根据指定的Model元数据所有特性创建出来,DataAnnotationsModelValidator只需要从中筛选出继承自ValiationAttribute的验证特性并创建对象的DataAnnotationsModelValidator就可以了。[本文已经同步到《How ASP.NET MVC Works?》中]
目录
DataAnnotationsModelValidator
基于ValidationAttribute的ModelValidator的创建
基于IValidatableObject的ModelValidator的创建
默认的ModelValidator创建机制
对ModelValidator创建方式的定制
我们现在结合DataAnnotationsModelValidator的相关定义来讨论一下具体的ModelValidator提供机制。如下面的代码片断所示,DataAnnotationsModelValidatorProvider具有两个静态的字段AttributeFactories和DefaultAttributeFactory,后者是一个DataAnnotationsModelValidationFactory委托,前者是以此委托为Value以Type对象为Key的字典。
1: public class DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider
4: internal static readonly Dictionary Type, DataAnnotationsModelValidationFactory AttributeFactories;
5: internal static DataAnnotationsModelValidationFactory DefaultAttributeFactory;
7: internal static DataAnnotationsValidatableObjectAdapterFactory DefaultValidatableFactory;
8: internal static readonly Dictionary Type, DataAnnotationsValidatableObjectAdapterFactory ValidatableFactories;
10: protected override IEnumerable ModelValidator GetValidators(ModelMetadata metadata, HttpActionContext actionContext, IEnumerable Attribute attributes);
13: public delegate ModelValidator DataAnnotationsModelValidationFactory(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute);
15: public delegate ModelValidator DataAnnotationsValidatableObjectAdapterFactory(ModelMetadata metadata, ControllerContext context);
基于ValidationAttribute的ModelValidator的创建
委托DataAnnotationsModelValidationFactory根据ModelMetadata、ControllerContext和ValidationAttribute返回一个ModelValidator对象,而字段AttributeFactories表示的字典对象的Key是具体的验证特性的类型,也就是说它维护一个ValidationAttribute特性类型和对应ModelValidator工厂的匹配关系。在重写的GetValidators方法中,针对指定的每一个ValidationAttribute,它先根据其类型从AttributeFactories中获取一个对应的DataAnnotationsModelValidationFactory委托,如果该委托存在,则用它来创建相应的ModelValidator对象;否则就采用字段DefaultAttributeFactory表示的DataAnnotationsModelValidationFactory委托来进行ModelValidator的创建。
基于IValidatableObject的ModelValidator的创建除了AttributeFactories和DefaultAttributeFactory,DataAnnotationsModelValidatorProvider还具有DefaultValidatableFactory和ValidatableFactories这两个静态属性,它们用于针对可验证对象(实现了IValidatableObject接口)的ModelValidator的创建。DataAnnotationsModelValidator的类型是另外一个类型为DataAnnotationsValidatableObjectAdapterFactory的委托,该委托根据ModelMetadata和ControllerContext创建相应的ModelValidator。ValidatableFactories是一个以此委托为Value,以Type对象为Key的字典。
当DataAnnotationsModelValidatorProvider完成了针对基于验证特性的ModelValidator的创建之后,如果根据Model元数据解析出来的Model类型实现了IValidatableObject接口,那么先从字典ValidatableFactories中根据此类型获取一个对应的DataAnnotationsValidatableObjectAdapterFactory委托,如果匹配的委托对象存在,则用其进行ModelValidator的创建;否则采用通过字段DefaultValidatableFactory表示的默认工厂来创建相应的ModelValidator对象。
默认的ModelValidator创建机制在DataAnnotationsModelValidatorProvider类型被加载的时候,上述的四个字段会在静态构造函数调用时被初始化。从如下的代码片断可看出,对于一般的ValidationAttribute,对应的ModelValidator是一个DataAnnotationsModelValidator对象(DefaultAttributeFactory字段);针对RangeAttribute、RegularExpressionAttribute 、RequiredAttribute和StringLengthAttribute这四种验证特性,它们对应的适配ModelValidator会被创建出来。而对于可验证对象来说,默认情况下提供的ModelValidator列表中还包含一个ValidatableObjectAdapter对象。
1: public class DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider
7: DefaultAttributeFactory = (metadata, context, attribute) = new DataAnnotationsModelValidator(metadata, context, attribute);
10: Dictionary Type, DataAnnotationsModelValidationFactory dictionary = new Dictionary Type, DataAnnotationsModelValidationFactory
11: dictionary.Add(typeof(RangeAttribute), (metadata, context, attribute) = new RangeAttributeAdapter(metadata, context, (RangeAttribute)attribute));
12: dictionary.Add(typeof(RegularExpressionAttribute), (metadata, context, attribute) = new RegularExpressionAttributeAdapter(metadata, context, (RegularExpressionAttribute)attribute));
13: dictionary.Add(typeof(RequiredAttribute), (metadata, context, attribute) = new RequiredAttributeAdapter(metadata, context, (RequiredAttribute)attribute));
14: dictionary.Add(typeof(StringLengthAttribute), (metadata, context, attribute) = new StringLengthAttributeAdapter(metadata, context,(StringLengthAttribute)attribute));
18: DefaultValidatableFactory = (metadata, context) = new ValidatableObjectAdapter(metadata, context);
21: ValidatableFactories = new Dictionary Type, DataAnnotationsValidatableObjectAdapterFactory
对ModelValidator创建方式的定制
DataAnnotationsModelValidatorProvider四个基于委托的静态字段体现了其采用的ModelValidator提供机制。由于它们都是内部字段,我们不能直接对其进行操作,但是如下所示的一系列静态方法在DataAnnotationsModelValidatorProvider中定义出来,使我们可以按照具体的需要对默认的ModelValidator进行定义。
1: public class DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider
4: public static void RegisterAdapter(Type attributeType, Type adapterType);
5: public static void RegisterAdapterFactory(Type attributeType, DataAnnotationsModelValidationFactory factory);
7: public static void RegisterDefaultAdapterFactory(DataAnnotationsModelValidationFactory factory);
9: public static void RegisterDefaultValidatableObjectAdapter(Type adapterType);
10: public static void RegisterDefaultValidatableObjectAdapterFactory(DataAnnotationsValidatableObjectAdapterFactory factory);
11: public static void RegisterValidatableObjectAdapter(Type modelType, Type adapterType);
12: public static void RegisterValidatableObjectAdapterFactory(Type modelType, DataAnnotationsValidatableObjectAdapterFactory factory);
对于上面的8个静态方法,除了RegisterDefaultAdapter和RegisterValidatableObjectAdapter之外,其余的都很好理解。RegisterDefaultAdapter用于注册一个默认的针对验证特性的ModelValidator类型,该类型必须具有一个参数类型列表为ModelMetadata、ControllerContext和Attribute的构造函数。如果根据 验证特性的类型找到了匹配的DataAnnotationsModelValidationFactory委托对象,相应的参数会被传入该构造函数并最终创建一个我们注册的ModelValidator对象。
RegisterValidatableObjectAdapter和RegisterDefaultAdapter比较类似,用于注册一个默认的针对可验证对象类型的ModelValidator,有该类型必须具有一个参数类型列表为ModelMetadata和ControllerContex的构造函数。如果根据 验证特性的类型找到了匹配的DataAnnotationsValidatableObjectAdapterFactory委托对象,相应的参数会被传入该构造函数并最终创建一个我们注册的ModelValidator对象。
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
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 原文链接
ASP.NET Core MVC 之模型(Model) ASP.NET Core MVC 之模型(Model) 1.模型绑定 ASP.NET Core MVC 中的模型绑定将数据从HTTP请求映射到操作方法参数。参数既可以是简单类型,也可以是复杂类型。
菜鸟入门【ASP.NET Core】15:MVC开发:ReturnUrl实现、Model后端验证 、Model前端验证 ReturnUrl实现 我们要实现returnUrl,我们需要在注册(Register)方法中接收传进的returnUrl并给它默认值null,然后将它保存在ViewData里面 然后我们定义一个内部方法来判断跳转returnUrl
Java Spring Boot开发实战系列课程【第7讲】:Spring Boot 2.0安全机制与MVC身份验证实战(Java面试题) 立即下载
相关文章
- How to restrict folder access in asp.net
- Why would one use a third-party DI Container over the built-in ASP.NET Core DI Container?
- .net core的安装
- EF Core使用SQL调用返回其他类型的查询 ASP.NET Core 2.0 使用NLog实现日志记录 CSS 3D transforms cSharp:use Activator.CreateInstance with an Interface? SqlHelper DBHelper C# Thread.Abort方法真的让线程停止了吗? 注意!你的Thread.Abort方法真
- ASP.NET没有魔法——ASP.NET MVC 模型绑定
- ASP.NET MVC和ASP.NET Web API跨域请求问题解决方案【最全】
- 如何让asp.net执行命令,暂停几秒,再执行下一行命令?(已解决)
- ASP.NET MVC请求处理管道生命周期的19个关键环节(7-12)
- ASP.NET - MVC框架及搭建教程
- 在ASP.NET MVC实现购物车,尝试一种不同于平常的购物车显示方式
- 在Windows Azure上创建ASP.NET MVC网站
- 在ASP.NET MVC中使用Knockout实践02,组合View Model成员、Select绑定、通过构造器创建View Model,扩展View Model方法
- 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC
- ASP.NET MVC 验证
- 《精通 ASP.NET MVC 3 框架(第三版)》----导读
- .NET Core Runtime IDentifier (RID) catalog
- 在Linux安装ASP.NET Core运行时环境
- 一、在 ASP.NET Core 中使用 SignalR
- vs 2019 .net core 3.1 asp.net mvc发布
- 教你如何在WINDOWS Server2003上部署一个Asp.Net的网站
- Asp.net Mvc Ajax.BeginForm提交表单
- ASP.NET Core MVC+EF Core从开发到部署
- C#基础 Asp.Net MVC EF各版本区别