福州建网站 做网页,wordpress 自定义页面 分页,网站description是指什么,郑州网站建设推广渠道ASP.NET MVC下的四种验证编程方式[续篇] 原文:ASP.NET MVC下的四种验证编程方式[续篇]在《ASP.NET MVC下的四种验证编程方式》一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式#xff08;“手工验证”、“标注ValidationAttribute特性”、“让数据类型实现IValida… ASP.NET MVC下的四种验证编程方式[续篇] 原文:ASP.NET MVC下的四种验证编程方式[续篇]在《ASP.NET MVC下的四种验证编程方式》一文中我们介绍了ASP.NET MVC支持的四种服务端验证的编程方式“手工验证”、“标注ValidationAttribute特性”、“让数据类型实现IValidatableObject或者IDataErrorInfo”那么在ASP.NET MVC框架内部是如何提供针对这四种不同编程方式的支持的呢接下来我们就来聊聊这背后的故事。 一、ModelValidator与ModelValidatorProvider 虽然Model绑定的方式因被验证数据类型的差异而有所不同但是ASP.NET MVC总是使用一个名为ModelValidator的对象来对绑定的数据对象实施验证。所有的ModelValidator类型均继承自具有如下定义的抽象类ModelValidator。它的GetClientValidationRules方法返回一个元素类型为ModelClientValidationRule的集合而ModelClientValidationRule是对客户端验证规则的封装我们会在客户端验证部分对其进行详细介绍。 1: public abstract class ModelValidator 2: { 3: //其他成员 4: public virtual IEnumerableModelClientValidationRule GetClientValidationRules(); 5: public abstract IEnumerableModelValidationResult Validate(object container); 6: 7: public virtual bool IsRequired { get; } 8: } 针对目标数据的验证是通过调用Validate方法来完成的该方法的输入参数container表示的正是被验证的对象。正是因为被验证的总是一个复杂类型的对象后者又被称为一个具有若干数据成员的“容器”对象所以对应的参数被命名为container。Validate方法表示验证结果的返回值并不是一个简单的布尔值而是一个元素类型为具有如下定义的ModelValidationResult对象集合。 1: public class ModelValidationResult 2: { 3: public string MemberName { get; set; } 4: public string Message { get; set; } 5: } ModelValidationResult具有两个字符串类型属性MemberName和Message前者代表被验证数据成员的名称后者表示错误消息。一般来说如果ModelValidationResult对象来源于针对容器对象本身的验证它的MemberName属性为空字符串。对于针对容器对象某个属性的验证来说属性名称会作为返回的ModelValidationResult对象的MemberName属性。 ModelValidationResult集合只有在验证失败的情况下才会返回。如果被验证数据对象符合所有的验证规则Validate方法会直接返回Null或者一个空ModelValidationResult集合。值得一提的是我们有时候会用ValidationResult的静态只读字段Success表示成功通过验证的结果实际上该字段的值就是Null。 1: public class ValidationResult 2: { 3: //其他成员 4: public static readonly ValidationResult Success; 5: } ModelValidator具有一个布尔类型的只读属性IsRequired表示该ModelValidator是否对目标数据进行“必需性”验证即被验证的数据成员必须具有一个具体的值该属性默认返回False。我们可以通过应用RequiredAttribute特性将某个属性定义成“必需”的数据成员。 我们知道ASP.NET MVC大都采用Provider的模式来提供相应的组件比如描述Model元数据的ModelMetadata通过对应的ModelMetadataProvider来提供实现Model绑定的ModelBinder则可以通过对应的ModelBinderProvider来提供用于实现Model验证的ModelValidator也不例外它对应的提供者为ModelValidatorProvider对应的类型继承自具有如下定义的抽象类ModelValidator Provider。 1: public abstract class ModelValidatorProvider 2: { 3: public abstract IEnumerableModelValidator GetValidators(ModelMetadata metadata, ControllerContext context); 4: } 如上面的代码片段所示GetValidators方法具有两个参数一个是用于描述被验证类型或者属性Model元数据的ModelMetadata对象另一个是当前ControllerContext。该方法返回的是一个元素类型为ModelValidator的集合。 ASP.NET MVC通过静态类型ModelValidatorProviders对使用的ModelValidatorProvider进行注册。如下面的代码片段所示ModelValidatorProviders具有一个静态只读属性Providers对应的类型为ModelValidatorProviderCollection它表示基于整个Web应用范围的全局ModelValidatorProvider集合。 1: public static class ModelValidatorProviders 2: { 3: public static ModelValidatorProviderCollection Providers { get; } 4: } 5: 6: public class ModelValidatorProviderCollection : CollectionModelValidatorProvider 7: { 8: public ModelValidatorProviderCollection(); 9: public ModelValidatorProviderCollection(IListModelValidatorProvider list); 10: public IEnumerableModelValidator GetValidators(ModelMetadata metadata, ControllerContext context); 11: } 值得一提的是用于描述Model元数据的ModelMetadata类型具有如下一个GetValidators方法它返回的ModelValidator列表正是利用注册到ModelValidatorProviders静态属性Providers上的ModelValidatorProvider创建的。 1: public class ModelMetadata 2: { 3: //其他成员 4: public virtual IEnumerableModelValidator GetValidators(ControllerContext context); 5: } 如右图所示的UML列出了组成Model验证系统的三个核心类型。具体的Model验证工作总是通过某个具体的ModelValidator来完成作为ModelValidator提供者的ModelValidatorProvider注册在静态类型ModelValidatorProviders之上。 二、DataAnnotationsModelValidator 我们在《ASP.NET MVC下的四种验证编程方式》中介绍了三种不同的“自动化验证”的编程方式ASP.NET MVC在内部会采用不同的ModelValidator来对绑定的参数实施验证。一个具体的ModelValidator通常有相应的ModelValidatorProvider来提供接下来的内容中将对ASP.NET MVC提供的原生的ModelValidator和对应的ModelValidatorProvider作详细的介绍。 对于上面提到的这三种验证编程方式第一种利用应用在数据类型或其数据成员上的ValidationAttribute特性来定义相应的验证规则是最为常用的。基于ValidationAttribute特性这种声明式验证解决方案最终通过DataAnnotationsModelValidator来完成。一个DataAnnotationsModelValidator对象实际上是对一个ValidationAttribute特性的封装这可以从如下所示的定义看出来。 1: public class DataAnnotationsModelValidator : ModelValidator 2: { 3: public DataAnnotationsModelValidator(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute); 4: public override IEnumerableModelClientValidationRule GetClientValidationRules(); 5: 6: public override IEnumerableModelValidationResult Validate(object container); 7: 8: protected internal ValidationAttribute Attribute { get; } 9: protected internal string ErrorMessage { get; } 10: public override bool IsRequired { get; } 11: } DataAnnotationsModelValidator的提供者为DataAnnotationsModelValidatorProvider,关于ValidationAttribute、DataAnnotationsModelValidator和DataAnnotationsModelValidatorProvider的详细内容可以参考之前写的三篇文章。 ASP.NET MVC基于标注特性的Model验证ValidationAttribute ASP.NET MVC基于标注特性的Model验证DataAnnotationsModelValidator ASP.NET MVC基于标注特性的Model验证DataAnnotationsModelValidatorProvider 三、ValidatableObjectAdapter 如果被验证的数据类型实现了IValidatable接口ASP.NET MVC会自动调用实现的Validate方法对其实施验证此时创建的ModelValidator是一个ValidatableObjectAdapter对象。ValidatableObjectAdapter定义如下其Validate方法的实现逻辑很简单它直接调用被验证对象的Validate方法并将返回的ValidationResult对象转换成ModelValidationResult类型。 1: public class ValidatableObjectAdapter : ModelValidator 2: { 3: public ValidatableObjectAdapter(ModelMetadata metadata, ControllerContext context); 4: public override IEnumerableModelValidationResult Validate(object container); 5: } 虽然ValidatableObjectAdapter继承自ModelValidator但是ASP.NET MVC貌似没有将其视为一个真正意义上的ModelValidator而是将其视为一个“适配器Adapter”。ASP.NET MVC也没有为ValidatableObjectAdapter定义单独的ModelValidatorProvider它的提供者其实是上面提到过的DataAnnotationsModelValidatorProvider。 四、DataErrorInfoModelValidator 如果我们让数据类型实现IDataErrorInfo接口可以利用实现的Error属性和索引提供针对自身以及所属数据成员的验证错误信息。针对这样的数据类型ASP.NET MVC最终会创建一个DataErrorInfoModelValidator对象来对其实施验证DataErrorInfoClassModelValidator和DataErrorInfoPropertyModelValidator是两个具体的DataErrorInfoModelValidator。 DataErrorInfoClassModelValidator和DataErrorInfoPropertyModelValidator是两个内部类型。前者针对容器对象自身实施验证所以它只需要从实现的Error属性中提取错误消息并将其转换成返回的ModelValidationResult对象。后者则专门验证容器对象的某个属性它在实现的Validate方法中会利用属性名从实现的索引中提取相应的错误消息并将其转换成返回的ModelValidationResult对象。 1: internal sealed class DataErrorInfoClassModelValidator : ModelValidator 2: { 3: public DataErrorInfoClassModelValidator(ModelMetadata metadata, ControllerContext controllerContext); 4: public override IEnumerableModelValidationResult Validate(object container); 5: } 6: 7: internal sealed class DataErrorInfoPropertyModelValidator : ModelValidator 8: { 9: public DataErrorInfoPropertyModelValidator(ModelMetadata metadata, ControllerContext controllerContext); 10: public override IEnumerableModelValidationResult Validate(object container); 11: } ASP.NET MVC最终利用具有如下定义的DataErrorInfoModelValidatorProvider来提供这两种类型的DataErrorInfoModelValidator。对于其实现的GetValidators方法来说如果被验证对象的类型实现了IDataErrorInfo接口它会创建一个DataErrorInfoClassModelValidator对象并添加到返回的ModelValidator列表中。如果被验证的是容器类型的某个属性值并且容器类型实现了IDataErrorInfo接口它会创建一个DataErrorInfoPropertyModelValidator对象并添加到返回的ModelValidator列表中。 1: public class DataErrorInfoModelValidatorProvider : ModelValidatorProvider 2: { 3: public override IEnumerableModelValidator GetValidators(ModelMetadata metadata, ControllerContext context); 4: } posted on 2014-06-28 15:22 NET未来之路 阅读(...) 评论(...) 编辑 收藏 转载于:https://www.cnblogs.com/lonelyxmas/p/3813400.html