当前位置:编程学习 > asp >>

Asp.net MVC源码分析--Model Validation(Server端)实现(2)

前面我们介绍了Model Validation的用法,以及ValidateModel的方法实现,这一篇我们来详细学习一下DataAnnotationsModelValidatorProvider类的实现。

三.DataAnnotationsModelValidatorProvider类详解
1.AttributeFactories对象
首先在这个类中可以看到在初始化时创建了AttributeFactories对象(Dictionary),  这个集合包含了系统内置一些验证规则。
 1         internal static Dictionary<Type, DataAnnotationsModelValidationFactory> AttributeFactories = new Dictionary<Type, DataAnnotationsModelValidationFactory>() {
 2             {
 3                 typeof(RangeAttribute),
 4                 (metadata, context, attribute) => new RangeAttributeAdapter(metadata, context, (RangeAttribute)attribute)
 5             },
 6             {
 7                 typeof(RegularExpressionAttribute),
 8                 (metadata, context, attribute) => new RegularExpressionAttributeAdapter(metadata, context, (RegularExpressionAttribute)attribute)
 9             },
10             {
11                 typeof(RequiredAttribute),
12                 (metadata, context, attribute) => new RequiredAttributeAdapter(metadata, context, (RequiredAttribute)attribute)
13             },
14             {
15                 typeof(StringLengthAttribute),
16                 (metadata, context, attribute) => new StringLengthAttributeAdapter(metadata, context, (StringLengthAttribute)attribute)
17             },
18         }
19 }
复制代码
2.ValidationAttribte 的 Adapter 设计模式应用
这里特别需要注意的是MVC利用了*AttributeAdapter 把 ValidationAttribte 的GetValidationResult方法和 ModelValidator.Validate方法作了一个适配(这里用到Adapter模式)请看RangeAttributeAdapter/RegularExpressionAttributeAdapter/RequiredAttributeAdapter/StringLengthAttributeAdapter
请参照DataAnnotationsModelValidator.Validate 方法源码,第7行代码,就是在这里进行了适配的工作。
 1  public override IEnumerable<ModelValidationResult> Validate(object container) {
 2             // Per the WCF RIA Services team, instance can never be null (if you have
 3 // no parent, you pass yourself for the "instance" parameter).
 4             ValidationContext context = new ValidationContext(container ?? Metadata.Model, null, null);
 5             context.DisplayName = Metadata.GetDisplayName();
 6
 7             ValidationResult result = Attribute.GetValidationResult(Metadata.Model, context);
 8             if (result != ValidationResult.Success) {
 9                 yield return new ModelValidationResult {
10                     Message = result.ErrorMessage
11                 };
12             }
13         }
复制代码
3.获取ModelValidator对象集合
接下来我们来分析一下DataAnnotationsModelValidatorProvider.GetValidators 方法的实现
 1  protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes) {
 2             _adaptersLock.EnterReadLock();
 3
 4             try {
 5                 List<ModelValidator> results = new List<ModelValidator>();
 6
 7                 // Add an implied [Required] attribute for any non-nullable value type,
 8 // unless they've configured us not to do that.
 9                 if (AddImplicitRequiredAttributeForValueTypes &&
10                         metadata.IsRequired &&
11                         !attributes.Any(a => a is RequiredAttribute)) {
12                     attributes = attributes.Concat(new[] { new RequiredAttribute() });
13                 }
14
15                 // Produce a validator for each validation attribute we find
16                 foreach (ValidationAttribute attribute in attributes.OfType<ValidationAttribute>()) {
17                     DataAnnotationsModelValidationFactory factory;
18                     if (!AttributeFactories.TryGetValue(attribute.GetType(), out factory)) {
19                         factory = DefaultAttributeFactory;
20                     }
21                     results.Add(factory(metadata, context, attribute));
22                 }
23
24&nbs

补充:Web开发 , ASP.Net ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,