Merge pull request #301 from directhex/master
[mono.git] / mcs / class / System.Web.Mvc3 / Mvc / DataErrorInfoModelValidatorProvider.cs
1 namespace System.Web.Mvc {
2     using System;
3     using System.Collections.Generic;
4     using System.ComponentModel;
5     using System.Linq;
6
7     public class DataErrorInfoModelValidatorProvider : ModelValidatorProvider {
8
9         public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) {
10             if (metadata == null) {
11                 throw new ArgumentNullException("metadata");
12             }
13             if (context == null) {
14                 throw new ArgumentNullException("context");
15             }
16
17             return GetValidatorsImpl(metadata, context);
18         }
19
20         private static IEnumerable<ModelValidator> GetValidatorsImpl(ModelMetadata metadata, ControllerContext context) {
21             // If the metadata describes a model that implements IDataErrorInfo, we should call its
22             // Error property at the appropriate time.
23             if (TypeImplementsIDataErrorInfo(metadata.ModelType)) {
24                 yield return new DataErrorInfoClassModelValidator(metadata, context);
25             }
26
27             // If the metadata describes a property of a container that implements IDataErrorInfo,
28             // we should call its Item indexer at the appropriate time.
29             if (TypeImplementsIDataErrorInfo(metadata.ContainerType)) {
30                 yield return new DataErrorInfoPropertyModelValidator(metadata, context);
31             }
32         }
33
34         private static bool TypeImplementsIDataErrorInfo(Type type) {
35             return typeof(IDataErrorInfo).IsAssignableFrom(type);
36         }
37
38         internal sealed class DataErrorInfoClassModelValidator : ModelValidator {
39             public DataErrorInfoClassModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
40                 : base(metadata, controllerContext) {
41             }
42             public override IEnumerable<ModelValidationResult> Validate(object container) {
43                 IDataErrorInfo castModel = Metadata.Model as IDataErrorInfo;
44                 if (castModel != null) {
45                     string errorMessage = castModel.Error;
46                     if (!String.IsNullOrEmpty(errorMessage)) {
47                         return new ModelValidationResult[] {
48                             new ModelValidationResult() { Message = errorMessage }
49                         };
50                     }
51                 }
52                 return Enumerable.Empty<ModelValidationResult>();
53             }
54         }
55
56         internal sealed class DataErrorInfoPropertyModelValidator : ModelValidator {
57             public DataErrorInfoPropertyModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
58                 : base(metadata, controllerContext) {
59             }
60             public override IEnumerable<ModelValidationResult> Validate(object container) {
61                 IDataErrorInfo castContainer = container as IDataErrorInfo;
62                 if (castContainer != null && !String.Equals(Metadata.PropertyName, "error", StringComparison.OrdinalIgnoreCase)) {
63                     string errorMessage = castContainer[Metadata.PropertyName];
64                     if (!String.IsNullOrEmpty(errorMessage)) {
65                         return new ModelValidationResult[] {
66                             new ModelValidationResult() { Message = errorMessage }
67                         };
68                     }
69                 }
70                 return Enumerable.Empty<ModelValidationResult>();
71             }
72         }
73
74     }
75 }