Merge pull request #1436 from esdrubal/readerwriterlockslim
[mono.git] / mcs / class / System.Web.Mvc3 / Mvc / AssociatedValidatorProvider.cs
1 namespace System.Web.Mvc {
2     using System;
3     using System.Collections.Generic;
4     using System.ComponentModel;
5     using System.ComponentModel.DataAnnotations;
6     using System.Globalization;
7     using System.Linq;
8     using System.Web.Mvc.Resources;
9
10     public abstract class AssociatedValidatorProvider : ModelValidatorProvider {
11         protected virtual ICustomTypeDescriptor GetTypeDescriptor(Type type) {
12             return TypeDescriptorHelper.Get(type);
13         }
14
15         public override sealed IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) {
16             if (metadata == null) {
17                 throw new ArgumentNullException("metadata");
18             }
19             if (context == null) {
20                 throw new ArgumentNullException("context");
21             }
22
23             if (metadata.ContainerType != null && !String.IsNullOrEmpty(metadata.PropertyName)) {
24                 return GetValidatorsForProperty(metadata, context);
25             }
26
27             return GetValidatorsForType(metadata, context);
28         }
29
30         protected abstract IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes);
31
32         private IEnumerable<ModelValidator> GetValidatorsForProperty(ModelMetadata metadata, ControllerContext context) {
33             ICustomTypeDescriptor typeDescriptor = GetTypeDescriptor(metadata.ContainerType);
34             PropertyDescriptor property = typeDescriptor.GetProperties().Find(metadata.PropertyName, true);
35             if (property == null) {
36                 throw new ArgumentException(
37                     String.Format(
38                         CultureInfo.CurrentCulture,
39                         MvcResources.Common_PropertyNotFound,
40                         metadata.ContainerType.FullName, metadata.PropertyName),
41                     "metadata");
42             }
43
44             return GetValidators(metadata, context, property.Attributes.OfType<Attribute>());
45         }
46
47         private IEnumerable<ModelValidator> GetValidatorsForType(ModelMetadata metadata, ControllerContext context) {
48             return GetValidators(metadata, context, GetTypeDescriptor(metadata.ModelType).GetAttributes().Cast<Attribute>());
49         }
50     }
51 }