Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ClientDataTypeModelValidatorProvider.cs « System.Web.Mvc « src - github.com/mono/aspnetwebstack.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 7a299350e85a9b2b41c197bca89f479ecb934bdc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.Mvc.Properties;

namespace System.Web.Mvc
{
    public class ClientDataTypeModelValidatorProvider : ModelValidatorProvider
    {
        private static readonly HashSet<Type> _numericTypes = new HashSet<Type>(new Type[]
        {
            typeof(byte), typeof(sbyte),
            typeof(short), typeof(ushort),
            typeof(int), typeof(uint),
            typeof(long), typeof(ulong),
            typeof(float), typeof(double), typeof(decimal)
        });

        private static string _resourceClassKey;

        public static string ResourceClassKey
        {
            get { return _resourceClassKey ?? String.Empty; }
            set { _resourceClassKey = value; }
        }

        public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
        {
            if (metadata == null)
            {
                throw new ArgumentNullException("metadata");
            }
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            return GetValidatorsImpl(metadata, context);
        }

        private static IEnumerable<ModelValidator> GetValidatorsImpl(ModelMetadata metadata, ControllerContext context)
        {
            Type type = metadata.ModelType;

            if (IsDateTimeType(type))
            {
                yield return new DateModelValidator(metadata, context);
            }

            if (IsNumericType(type))
            {
                yield return new NumericModelValidator(metadata, context);
            }
        }

        private static bool IsNumericType(Type type)
        {
            return _numericTypes.Contains(GetTypeToValidate(type));
        }

        private static bool IsDateTimeType(Type type)
        {
            return typeof(DateTime) == GetTypeToValidate(type);
        }

        private static Type GetTypeToValidate(Type type)
        {
            return Nullable.GetUnderlyingType(type) ?? type; // strip off the Nullable<>
        }

        // If the user specified a ResourceClassKey try to load the resource they specified.
        // If the class key is invalid, an exception will be thrown.
        // If the class key is valid but the resource is not found, it returns null, in which
        // case it will fall back to the MVC default error message.
        private static string GetUserResourceString(ControllerContext controllerContext, string resourceName)
        {
            string result = null;

            if (!String.IsNullOrEmpty(ResourceClassKey) && (controllerContext != null) && (controllerContext.HttpContext != null))
            {
                result = controllerContext.HttpContext.GetGlobalResourceObject(ResourceClassKey, resourceName, CultureInfo.CurrentUICulture) as string;
            }

            return result;
        }

        private static string GetFieldMustBeNumericResource(ControllerContext controllerContext)
        {
            return GetUserResourceString(controllerContext, "FieldMustBeNumeric") ?? MvcResources.ClientDataTypeModelValidatorProvider_FieldMustBeNumeric;
        }

        private static string GetFieldMustBeDateResource(ControllerContext controllerContext)
        {
            return GetUserResourceString(controllerContext, "FieldMustBeDate") ?? MvcResources.ClientDataTypeModelValidatorProvider_FieldMustBeDate;
        }

        internal class ClientModelValidator : ModelValidator
        {
            private string _errorMessage;
            private string _validationType;

            public ClientModelValidator(ModelMetadata metadata, ControllerContext controllerContext, string validationType, string errorMessage)
                : base(metadata, controllerContext)
            {
                if (String.IsNullOrEmpty(validationType))
                {
                    throw new ArgumentException(MvcResources.Common_NullOrEmpty, "validationType");
                }

                if (String.IsNullOrEmpty(errorMessage))
                {
                    throw new ArgumentException(MvcResources.Common_NullOrEmpty, "errorMessage");
                }

                _validationType = validationType;
                _errorMessage = errorMessage;
            }

            public sealed override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
            {
                ModelClientValidationRule rule = new ModelClientValidationRule()
                {
                    ValidationType = _validationType,
                    ErrorMessage = FormatErrorMessage(Metadata.GetDisplayName())
                };

                return new ModelClientValidationRule[] { rule };
            }

            private string FormatErrorMessage(string displayName)
            {
                // use CurrentCulture since this message is intended for the site visitor
                return String.Format(CultureInfo.CurrentCulture, _errorMessage, displayName);
            }

            public sealed override IEnumerable<ModelValidationResult> Validate(object container)
            {
                // this is not a server-side validator
                return Enumerable.Empty<ModelValidationResult>();
            }
        }

        internal sealed class DateModelValidator : ClientModelValidator
        {
            public DateModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
                : base(metadata, controllerContext, "date", GetFieldMustBeDateResource(controllerContext))
            {
            }
        }

        internal sealed class NumericModelValidator : ClientModelValidator
        {
            public NumericModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
                : base(metadata, controllerContext, "number", GetFieldMustBeNumericResource(controllerContext))
            {
            }
        }
    }
}