1 namespace System.Web.Mvc { 2 using System; 3 using System.Collections.Generic; 4 using System.Globalization; 5 using System.Linq; 6 using System.Web.Mvc.Resources; 7 8 public class ClientDataTypeModelValidatorProvider : ModelValidatorProvider { 9 10 private static readonly HashSet<Type> _numericTypes = new HashSet<Type>(new Type[] { 11 typeof(byte), typeof(sbyte), 12 typeof(short), typeof(ushort), 13 typeof(int), typeof(uint), 14 typeof(long), typeof(ulong), 15 typeof(float), typeof(double), typeof(decimal) 16 }); 17 GetValidators(ModelMetadata metadata, ControllerContext context)18 public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context) { 19 if (metadata == null) { 20 throw new ArgumentNullException("metadata"); 21 } 22 if (context == null) { 23 throw new ArgumentNullException("context"); 24 } 25 26 return GetValidatorsImpl(metadata, context); 27 } 28 GetValidatorsImpl(ModelMetadata metadata, ControllerContext context)29 private static IEnumerable<ModelValidator> GetValidatorsImpl(ModelMetadata metadata, ControllerContext context) { 30 Type type = metadata.ModelType; 31 if (IsNumericType(type)) { 32 yield return new NumericModelValidator(metadata, context); 33 } 34 } 35 IsNumericType(Type type)36 private static bool IsNumericType(Type type) { 37 Type underlyingType = Nullable.GetUnderlyingType(type); // strip off the Nullable<> 38 return _numericTypes.Contains(underlyingType ?? type); 39 } 40 41 internal sealed class NumericModelValidator : ModelValidator { NumericModelValidator(ModelMetadata metadata, ControllerContext controllerContext)42 public NumericModelValidator(ModelMetadata metadata, ControllerContext controllerContext) 43 : base(metadata, controllerContext) { 44 } 45 GetClientValidationRules()46 public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() { 47 ModelClientValidationRule rule = new ModelClientValidationRule() { 48 ValidationType = "number", 49 ErrorMessage = MakeErrorString(Metadata.GetDisplayName()) 50 }; 51 52 return new ModelClientValidationRule[] { rule }; 53 } 54 MakeErrorString(string displayName)55 private static string MakeErrorString(string displayName) { 56 // use CurrentCulture since this message is intended for the site visitor 57 return String.Format(CultureInfo.CurrentCulture, MvcResources.ClientDataTypeModelValidatorProvider_FieldMustBeNumeric, displayName); 58 } 59 Validate(object container)60 public override IEnumerable<ModelValidationResult> Validate(object container) { 61 // this is not a server-side validator 62 return Enumerable.Empty<ModelValidationResult>(); 63 } 64 } 65 66 } 67 } 68