diff --git a/src/Microsoft.AspNet.Mvc.Core/Controller.cs b/src/Microsoft.AspNet.Mvc.Core/Controller.cs index 3510736fb1..06d1c9414b 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Controller.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Controller.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Routing; using Microsoft.Framework.Internal; diff --git a/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvoker.cs index 705c062781..222f8b8cee 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvoker.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.ModelBinding; -using Microsoft.Framework.DependencyInjection; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.Core diff --git a/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvokerProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvokerProvider.cs index f5dc3a3c7a..2e2497808d 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvokerProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ControllerActionInvokerProvider.cs @@ -1,11 +1,10 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNet.Mvc.ModelBinding; -using Microsoft.Framework.DependencyInjection; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.Core diff --git a/src/Microsoft.AspNet.Mvc.Core/DefaultControllerActionArgumentBinder.cs b/src/Microsoft.AspNet.Mvc.Core/DefaultControllerActionArgumentBinder.cs index ba0f384dd4..d9fdabe77a 100644 --- a/src/Microsoft.AspNet.Mvc.Core/DefaultControllerActionArgumentBinder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/DefaultControllerActionArgumentBinder.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding.Metadata; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Mvc diff --git a/src/Microsoft.AspNet.Mvc.Core/DefaultValidationExcludeFiltersProvider.cs b/src/Microsoft.AspNet.Mvc.Core/DefaultValidationExcludeFiltersProvider.cs index 6a303e6dd6..4d8a6816e3 100644 --- a/src/Microsoft.AspNet.Mvc.Core/DefaultValidationExcludeFiltersProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/DefaultValidationExcludeFiltersProvider.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; -using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Mvc.OptionDescriptors diff --git a/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs index 80683d4c7b..ac08004838 100644 --- a/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs @@ -8,7 +8,7 @@ using System.Linq; using System.Runtime.ExceptionServices; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.ModelBinding; -using Microsoft.Framework.DependencyInjection; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.Core diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/ResourceExecutingContext.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/ResourceExecutingContext.cs index 3618d1dcdd..0350f78566 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Filters/ResourceExecutingContext.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Filters/ResourceExecutingContext.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; namespace Microsoft.AspNet.Mvc { diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeBasedExcludeFilter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeBasedExcludeFilter.cs index 2147a186f8..86dac927c5 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeBasedExcludeFilter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeBasedExcludeFilter.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc diff --git a/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeNameBasedExcludeFilter.cs b/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeNameBasedExcludeFilter.cs index 5c2aef77df..25be7d9272 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeNameBasedExcludeFilter.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Formatters/DefaultTypeNameBasedExcludeFilter.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc diff --git a/src/Microsoft.AspNet.Mvc.Core/Internal/ModelClientValidationRemoteRule.cs b/src/Microsoft.AspNet.Mvc.Core/Internal/ModelClientValidationRemoteRule.cs index 272ba952d6..36fb41d8e7 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Internal/ModelClientValidationRemoteRule.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Internal/ModelClientValidationRemoteRule.cs @@ -1,8 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; namespace Microsoft.AspNet.Mvc.Internal { diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinders/BodyModelBinder.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinders/BodyModelBinder.cs index 7886446d0d..0d9d7aa7da 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinders/BodyModelBinder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinders/BodyModelBinder.cs @@ -6,6 +6,9 @@ using System.Linq; using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Core; +using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; +using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.ModelBinding diff --git a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs index 4afa9f3bf0..86a4a7f8c4 100644 --- a/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs @@ -84,7 +84,7 @@ namespace Microsoft.AspNet.Mvc /// /// Gets a list of which are used to construct a list - /// of exclude filters by . + /// of exclude filters by . /// public IList ValidationExcludeFilters { get; } @@ -115,7 +115,7 @@ namespace Microsoft.AspNet.Mvc /// /// Gets a list of the s used by - /// . + /// . /// public IList ModelValidatorProviders { get; } diff --git a/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/DefaultModelValidatorProviderProvider.cs b/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/DefaultModelValidatorProviderProvider.cs index 87cf7815a3..dd26fe75f2 100644 --- a/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/DefaultModelValidatorProviderProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/DefaultModelValidatorProviderProvider.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; -using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.OptionsModel; namespace Microsoft.AspNet.Mvc.OptionDescriptors diff --git a/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ExcludeValidationDescriptor.cs b/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ExcludeValidationDescriptor.cs index 8ab99ee608..9bdaf87dc8 100644 --- a/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ExcludeValidationDescriptor.cs +++ b/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ExcludeValidationDescriptor.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.OptionDescriptors diff --git a/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ModelValidatorProviderDescriptor.cs b/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ModelValidatorProviderDescriptor.cs index 389ca67062..ca1ef139fa 100644 --- a/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ModelValidatorProviderDescriptor.cs +++ b/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ModelValidatorProviderDescriptor.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.OptionDescriptors diff --git a/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ModelValidatorProviderDescriptorExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ModelValidatorProviderDescriptorExtensions.cs index 8e40b20f69..2ee3317f8c 100644 --- a/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ModelValidatorProviderDescriptorExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ModelValidatorProviderDescriptorExtensions.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; -using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.OptionDescriptors; using Microsoft.Framework.Internal; @@ -57,7 +57,7 @@ namespace Microsoft.AspNet.Mvc /// Adds an to . /// /// A list of . - /// An instance. + /// An instance. /// A representing the added instance. public static ModelValidatorProviderDescriptor Add( [NotNull] this IList descriptors, @@ -75,7 +75,7 @@ namespace Microsoft.AspNet.Mvc /// A list of . /// The zero-based index at which /// should be inserted. - /// An instance. + /// An instance. /// A representing the added instance. public static ModelValidatorProviderDescriptor Insert( [NotNull] this IList descriptors, diff --git a/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ValidationExcludeFiltersExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ValidationExcludeFiltersExtensions.cs index 09d346918c..0da40bf590 100644 --- a/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ValidationExcludeFiltersExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/OptionDescriptors/ValidationExcludeFiltersExtensions.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; -using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.OptionDescriptors; namespace Microsoft.AspNet.Mvc diff --git a/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/ActionBindingContext.cs b/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/ActionBindingContext.cs index 775f1f7c3c..925f9f5e07 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/ActionBindingContext.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/ActionBindingContext.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; namespace Microsoft.AspNet.Mvc { diff --git a/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/ModelBindingHelper.cs b/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/ModelBindingHelper.cs index d27d5217ed..3b7a09de81 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/ModelBindingHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ParameterBinding/ModelBindingHelper.cs @@ -12,6 +12,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc diff --git a/src/Microsoft.AspNet.Mvc.Core/RemoteAttribute.cs b/src/Microsoft.AspNet.Mvc.Core/RemoteAttribute.cs index d7c3060268..5de4ed2630 100644 --- a/src/Microsoft.AspNet.Mvc.Core/RemoteAttribute.cs +++ b/src/Microsoft.AspNet.Mvc.Core/RemoteAttribute.cs @@ -8,7 +8,7 @@ using System.Globalization; using System.Linq; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.Internal; -using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Routing; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultHtmlGenerator.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultHtmlGenerator.cs index db10625be2..97443f5e05 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultHtmlGenerator.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/DefaultHtmlGenerator.cs @@ -10,8 +10,8 @@ using System.Linq; using System.Text; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.Rendering.Expressions; -using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; using Microsoft.Framework.WebEncoders; @@ -746,9 +746,14 @@ namespace Microsoft.AspNet.Mvc.Rendering modelExplorer.Metadata, _metadataProvider, viewContext.HttpContext.RequestServices); + + var validatorProviderContext = new ModelValidatorProviderContext(modelExplorer.Metadata); + validatorProvider.GetValidators(validatorProviderContext); - return validatorProvider - .GetValidators(modelExplorer.Metadata) + var validators = validatorProviderContext.Validators; + + return + validators .OfType() .SelectMany(v => v.GetClientValidationRules(validationContext)); } diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs index 23b15cc092..8de7be9913 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs @@ -9,6 +9,7 @@ using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.Rendering.Expressions; using Microsoft.Framework.Internal; using Microsoft.Framework.WebEncoders; diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/IHtmlGenerator.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/IHtmlGenerator.cs index 6938d24ca0..4646b6e8ad 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/IHtmlGenerator.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/IHtmlGenerator.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.Rendering diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs index 48cc8df723..c88702865a 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; using Microsoft.Framework.WebEncoders; diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/UnobtrusiveValidationAttributesGenerator.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/UnobtrusiveValidationAttributesGenerator.cs index 04e28700a9..a2d769cf00 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/UnobtrusiveValidationAttributesGenerator.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/UnobtrusiveValidationAttributesGenerator.cs @@ -5,7 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNet.Mvc.Core; -using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.Rendering diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/MutableObjectModelBinder.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/MutableObjectModelBinder.cs index 3f6b1d99f1..d329c85376 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/MutableObjectModelBinder.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Binders/MutableObjectModelBinder.cs @@ -9,7 +9,7 @@ using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.ModelBinding.Internal; using Microsoft.AspNet.Mvc.ModelBinding.Metadata; -using Microsoft.Framework.DependencyInjection; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; namespace Microsoft.AspNet.Mvc.ModelBinding { @@ -326,10 +326,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding continue; } - var requiredValidator = bindingContext.OperationBindingContext - .ValidatorProvider - .GetValidators(propertyMetadata) - .FirstOrDefault(v => v != null && v.IsRequired); + var validatorProviderContext = new ModelValidatorProviderContext(propertyMetadata); + bindingContext.OperationBindingContext.ValidatorProvider.GetValidators(validatorProviderContext); + + var requiredValidator = validatorProviderContext.Validators + .FirstOrDefault(v => v != null && v.IsRequired); if (requiredValidator != null) { validationInfo.RequiredValidators[propertyName] = requiredValidator; diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DataAnnotationsMetadataDetailsProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DataAnnotationsMetadataProvider.cs similarity index 93% rename from src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DataAnnotationsMetadataDetailsProvider.cs rename to src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DataAnnotationsMetadataProvider.cs index 45e10e522b..6ae291a1d2 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DataAnnotationsMetadataDetailsProvider.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DataAnnotationsMetadataProvider.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using Microsoft.Framework.Internal; @@ -12,9 +11,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata /// An implementation of and for /// the System.ComponentModel.DataAnnotations attribute classes. /// - public class DataAnnotationsMetadataDetailsProvider : + public class DataAnnotationsMetadataProvider : IBindingMetadataProvider, - IDisplayMetadataProvider + IDisplayMetadataProvider, + IValidationMetadataProvider { /// public void GetBindingMetadata([NotNull] BindingMetadataProviderContext context) @@ -167,5 +167,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata displayMetadata.TemplateHint = "HiddenInput"; } } + + /// + public void GetValidationMetadata([NotNull] ValidationMetadataProviderContext context) + { + foreach (var attribute in context.Attributes.OfType()) + { + context.ValidationMetadata.ValiatorMetadata.Add(attribute); + } + } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DataMemberBindingMetadataProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DataMemberBindingMetadataProvider.cs new file mode 100644 index 0000000000..7d31b558b8 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DataMemberBindingMetadataProvider.cs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization; +using Microsoft.Framework.Internal; + +namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata +{ + /// + /// An for . + /// + public class DataMemberRequiredValidationMetadataProvider : IBindingMetadataProvider + { + /// + public void GetBindingMetadata([NotNull] BindingMetadataProviderContext context) + { + // Types cannot be required; only properties can + if (context.Key.MetadataKind != ModelMetadataKind.Property) + { + return; + } + + var dataMemberAttribute = context + .Attributes + .OfType() + .FirstOrDefault(); + if (dataMemberAttribute == null || !dataMemberAttribute.IsRequired) + { + return; + } + + // isDataContract == true iff the container type has at least one DataContractAttribute + var containerType = context.Key.ContainerType.GetTypeInfo(); + var isDataContract = containerType.GetCustomAttribute() != null; + if (isDataContract) + { + // We don't need to add a validator, just to set IsRequired = true. The validation + // system will do the right thing. + context.BindingMetadata.IsRequired = true; + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DefaultModelMetadata.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DefaultModelMetadata.cs index c83a27c330..9ad5e8369b 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DefaultModelMetadata.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DefaultModelMetadata.cs @@ -22,6 +22,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata private bool? _isReadOnly; private bool? _isRequired; private ModelPropertyCollection _properties; + private ReadOnlyCollection _validatorMetadata; /// /// Creates a new . @@ -356,5 +357,19 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata return DisplayMetadata.TemplateHint; } } + + /// + public override IReadOnlyList ValidatorMetadata + { + get + { + if (_validatorMetadata == null) + { + _validatorMetadata = new ReadOnlyCollection(ValidationMetadata.ValiatorMetadata); + } + + return _validatorMetadata; + } + } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DefaultModelMetadataProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DefaultModelMetadataProvider.cs index ed7f748980..efa50bdb75 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DefaultModelMetadataProvider.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DefaultModelMetadataProvider.cs @@ -88,10 +88,39 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata { var propertyHelpers = PropertyHelper.GetProperties(key.ModelType); - var propertyEntries = new DefaultMetadataDetailsCache[propertyHelpers.Length]; + var propertyEntries = new List(propertyHelpers.Length); for (var i = 0; i < propertyHelpers.Length; i++) { var propertyHelper = propertyHelpers[i]; + if (propertyHelper.Property.DeclaringType != key.ModelType) + { + // If this property was declared on a base type then look for the definition closest to the + // the model type to see if we should include it. + var ignoreProperty = false; + + // Walk up the hierarchy until we find the type that actally declares this + // PropertyInfo. + var currentType = key.ModelType.GetTypeInfo(); + while (currentType != propertyHelper.Property.DeclaringType.GetTypeInfo()) + { + // We've found a 'more proximal' public definition + var declaredProperty = currentType.GetDeclaredProperty(propertyHelper.Name); + if (declaredProperty != null) + { + ignoreProperty = true; + break; + } + + currentType = currentType.BaseType.GetTypeInfo(); + } + + if (ignoreProperty) + { + // There's a better definition, ignore this. + continue; + } + } + var propertyKey = ModelMetadataIdentity.ForProperty( propertyHelper.Property.PropertyType, propertyHelper.Name, @@ -101,19 +130,21 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata key.ModelType, propertyHelper.Property)); - propertyEntries[i] = new DefaultMetadataDetailsCache(propertyKey, attributes); + var propertyEntry = new DefaultMetadataDetailsCache(propertyKey, attributes); if (propertyHelper.Property.CanRead && propertyHelper.Property.GetMethod?.IsPrivate == true) { - propertyEntries[i].PropertyAccessor = PropertyHelper.MakeFastPropertyGetter(propertyHelper.Property); + propertyEntry.PropertyAccessor = PropertyHelper.MakeFastPropertyGetter(propertyHelper.Property); } if (propertyHelper.Property.CanWrite && propertyHelper.Property.SetMethod?.IsPrivate == true) { - propertyEntries[i].PropertySetter = PropertyHelper.MakeFastPropertySetter(propertyHelper.Property); + propertyEntry.PropertySetter = PropertyHelper.MakeFastPropertySetter(propertyHelper.Property); } + + propertyEntries.Add(propertyEntry); } - return propertyEntries; + return propertyEntries.ToArray(); } /// diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DefaultValidationMetadataProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DefaultValidationMetadataProvider.cs new file mode 100644 index 0000000000..cb6b919511 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/DefaultValidationMetadataProvider.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Linq; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; +using Microsoft.Framework.Internal; + +namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata +{ + /// + /// A default implementation of . + /// + public class DefaultValidationMetadataProvider : IValidationMetadataProvider + { + /// + public void GetValidationMetadata([NotNull] ValidationMetadataProviderContext context) + { + foreach (var attribute in context.Attributes.OfType()) + { + context.ValidationMetadata.ValiatorMetadata.Add(attribute); + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/IMetadataDetailsProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/IMetadataDetailsProvider.cs index cf6f8831e4..9625bb423c 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/IMetadataDetailsProvider.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/IMetadataDetailsProvider.cs @@ -6,7 +6,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata /// /// Marker interface for a provider of metadata details about model objects. Implementations should /// implement one or more of , , - /// and . + /// and . /// public interface IMetadataDetailsProvider { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/ValidationMetadata.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/ValidationMetadata.cs index 51acc5de88..51b8775a7e 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/ValidationMetadata.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Metadata/ValidationMetadata.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Collections.Generic; + namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata { /// @@ -8,5 +10,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata /// public class ValidationMetadata { + /// + /// Gets a list of metadata items for validators. + /// + /// + /// implementations should store metadata items + /// in this list, to be consumed later by an . + /// + public IList ValiatorMetadata { get; } = new List(); } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/ModelMetadata.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/ModelMetadata.cs index 4e7434679b..a166a0d505 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/ModelMetadata.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/ModelMetadata.cs @@ -199,6 +199,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding /// public abstract string TemplateHint { get; } + /// + /// Gets a collection of metadata items for validators. + /// + public abstract IReadOnlyList ValidatorMetadata { get;} + /// /// Gets a value indicating whether is a simple type. /// diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/OperationBindingContext.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/OperationBindingContext.cs index 49b8196abe..8160ec6fb2 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/OperationBindingContext.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/OperationBindingContext.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNet.Http; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; namespace Microsoft.AspNet.Mvc.ModelBinding { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/AssociatedValidatorProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/AssociatedValidatorProvider.cs deleted file mode 100644 index 9a8b306b9a..0000000000 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/AssociatedValidatorProvider.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Microsoft.Framework.Internal; - -namespace Microsoft.AspNet.Mvc.ModelBinding -{ - public abstract class AssociatedValidatorProvider : IModelValidatorProvider - { - public IEnumerable GetValidators([NotNull] ModelMetadata metadata) - { - if (metadata.ContainerType != null && !string.IsNullOrEmpty(metadata.PropertyName)) - { - return GetValidatorsForProperty(metadata); - } - - return GetValidatorsForType(metadata); - } - - protected abstract IEnumerable GetValidators(ModelMetadata metadata, - IEnumerable attributes); - - private IEnumerable GetValidatorsForProperty(ModelMetadata metadata) - { - var propertyName = metadata.PropertyName; - var bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase; - var property = metadata.ContainerType - .GetProperty(propertyName, bindingFlags); - - if (property == null) - { - throw new ArgumentException( - Resources.FormatCommon_PropertyNotFound( - metadata.ContainerType.FullName, - metadata.PropertyName), - "metadata"); - } - - var attributes = ModelAttributes.GetAttributesForProperty(metadata.ContainerType, property); - return GetValidators(metadata, attributes); - } - - private IEnumerable GetValidatorsForType(ModelMetadata metadata) - { - var attributes = ModelAttributes.GetAttributesForType(metadata.ModelType); - - return GetValidators(metadata, attributes); - } - } -} diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ClientModelValidationContext.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ClientModelValidationContext.cs index 3b2a0df500..3ef5653ff5 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ClientModelValidationContext.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ClientModelValidationContext.cs @@ -4,7 +4,7 @@ using System; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class ClientModelValidationContext { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/CompareAttributeAdapter.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/CompareAttributeAdapter.cs index 5c8f0093aa..2239c7d4a7 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/CompareAttributeAdapter.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/CompareAttributeAdapter.cs @@ -6,7 +6,7 @@ using System.ComponentModel.DataAnnotations; using System.Globalization; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class CompareAttributeAdapter : DataAnnotationsModelValidator { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/CompositeModelValidatorProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/CompositeModelValidatorProvider.cs index f949feabb6..ff4751429a 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/CompositeModelValidatorProvider.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/CompositeModelValidatorProvider.cs @@ -2,10 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Linq; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { /// /// Default implementation for . @@ -25,9 +24,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding public IReadOnlyList ValidatorProviders { get; } - public IEnumerable GetValidators(ModelMetadata metadata) + public void GetValidators(ModelValidatorProviderContext context) { - return ValidatorProviders.SelectMany(v => v.GetValidators(metadata)); + foreach (var validatorProvider in ValidatorProviders) + { + validatorProvider.GetValidators(context); + } } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataAnnotationsModelValidator.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataAnnotationsModelValidator.cs index 24d70780c4..f01b2c3d13 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataAnnotationsModelValidator.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataAnnotationsModelValidator.cs @@ -7,7 +7,7 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class DataAnnotationsModelValidator : IModelValidator, IClientModelValidator { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataAnnotationsModelValidatorOfTAttribute.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataAnnotationsModelValidatorOfTAttribute.cs index e7c6d4abe9..653dc58b1a 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataAnnotationsModelValidatorOfTAttribute.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataAnnotationsModelValidatorOfTAttribute.cs @@ -3,7 +3,7 @@ using System.ComponentModel.DataAnnotations; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class DataAnnotationsModelValidator : DataAnnotationsModelValidator where TAttribute : ValidationAttribute diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataAnnotationsModelValidatorProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataAnnotationsModelValidatorProvider.cs index 1231db90ef..8487181e25 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataAnnotationsModelValidatorProvider.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataAnnotationsModelValidatorProvider.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { /// /// An implementation of which providers validators @@ -17,7 +17,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding /// . The logic to support /// is implemented in . /// - public class DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider + public class DataAnnotationsModelValidatorProvider : IModelValidatorProvider { // A factory for validators based on ValidationAttribute. internal delegate IModelValidator DataAnnotationsModelValidationFactory(ValidationAttribute attribute); @@ -30,7 +30,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding private static readonly DataAnnotationsValidatableObjectAdapterFactory _defaultValidatableFactory = () => new ValidatableObjectAdapter(); - private static bool _addImplicitRequiredAttributeForValueTypes = true; private readonly Dictionary _attributeFactories = BuildAttributeFactoriesDictionary(); @@ -42,35 +41,24 @@ namespace Microsoft.AspNet.Mvc.ModelBinding get { return _attributeFactories; } } - private static bool AddImplicitRequiredAttributeForValueTypes + public void GetValidators(ModelValidatorProviderContext context) { - get { return _addImplicitRequiredAttributeForValueTypes; } - set { _addImplicitRequiredAttributeForValueTypes = value; } - } - - protected override IEnumerable GetValidators(ModelMetadata metadata, - IEnumerable attributes) - { - var results = new List(); - - // Produce a validator for each validation attribute we find - foreach (var attribute in attributes.OfType()) + foreach (var attribute in context.ValidatorMetadata.OfType()) { DataAnnotationsModelValidationFactory factory; if (!_attributeFactories.TryGetValue(attribute.GetType(), out factory)) { factory = _defaultAttributeFactory; } - results.Add(factory(attribute)); + + context.Validators.Add(factory(attribute)); } // Produce a validator if the type supports IValidatableObject - if (typeof(IValidatableObject).IsAssignableFrom(metadata.ModelType)) + if (typeof(IValidatableObject).IsAssignableFrom(context.ModelMetadata.ModelType)) { - results.Add(_defaultValidatableFactory()); + context.Validators.Add(_defaultValidatableFactory()); } - - return results; } private static Dictionary BuildAttributeFactoriesDictionary() diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataMemberModelValidatorProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataMemberModelValidatorProvider.cs deleted file mode 100644 index e5ecc1132a..0000000000 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataMemberModelValidatorProvider.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Runtime.Serialization; - -namespace Microsoft.AspNet.Mvc.ModelBinding -{ - /// - /// This provides a required ModelValidator for members marked - /// as [DataMember(IsRequired=true)]. - /// - public class DataMemberModelValidatorProvider : AssociatedValidatorProvider - { - protected override IEnumerable GetValidators(ModelMetadata metadata, - IEnumerable attributes) - { - // Types cannot be required; only properties can - if (metadata.ContainerType == null || string.IsNullOrEmpty(metadata.PropertyName)) - { - return Enumerable.Empty(); - } - - if (IsRequiredDataMember(metadata.ContainerType, attributes)) - { - return new[] { new RequiredMemberModelValidator() }; - } - - return Enumerable.Empty(); - } - - internal static bool IsRequiredDataMember(Type containerType, IEnumerable attributes) - { - var dataMemberAttribute = attributes.OfType() - .FirstOrDefault(); - if (dataMemberAttribute != null) - { - // isDataContract == true iff the container type has at least one DataContractAttribute - var isDataContract = containerType.GetTypeInfo() - .GetCustomAttributes() - .OfType() - .Any(); - if (isDataContract && dataMemberAttribute.IsRequired) - { - return true; - } - } - return false; - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataTypeAttributeAdapter.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataTypeAttributeAdapter.cs index d17384275e..ba6aad4407 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataTypeAttributeAdapter.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DataTypeAttributeAdapter.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { /// /// A validation adapter that is used to map 's to a single client side validation diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultModelValidatorProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultModelValidatorProvider.cs new file mode 100644 index 0000000000..9163b3aaee --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultModelValidatorProvider.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation +{ + /// + /// A default . + /// + /// + /// The provides validators from + /// instances in . + /// + public class DefaultModelValidatorProvider : IModelValidatorProvider + { + /// + public void GetValidators(ModelValidatorProviderContext context) + { + foreach (var metadata in context.ValidatorMetadata) + { + var validator = metadata as IModelValidator; + if (validator != null) + { + context.Validators.Add(validator); + } + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultObjectValidator.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultObjectValidator.cs index 40cdae9bfc..952b596996 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultObjectValidator.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/DefaultObjectValidator.cs @@ -10,7 +10,7 @@ using System.Runtime.CompilerServices; using Microsoft.AspNet.Mvc.ModelBinding.Internal; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { /// /// Recursively validate an object. @@ -49,7 +49,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding string modelKey, ModelExplorer modelExplorer, ValidationContext validationContext, - IEnumerable validators) + IList validators) { // Recursion guard to avoid stack overflows RuntimeHelpers.EnsureSufficientExecutionStack(); @@ -84,7 +84,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding // the same for all the elements of the array, we do not do GetValidators for each element, // instead we just pass them over. See ValidateElements function. var validatorProvider = validationContext.ModelValidationContext.ValidatorProvider; - validators = validatorProvider.GetValidators(modelExplorer.Metadata); + var validatorProviderContext = new ModelValidatorProviderContext(modelExplorer.Metadata); + validatorProvider.GetValidators(validatorProviderContext); + + validators = validatorProviderContext.Validators; } // We don't need to recursively traverse the graph for null values @@ -186,7 +189,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var elementType = GetElementType(model.GetType()); var elementMetadata = _modelMetadataProvider.GetMetadataForType(elementType); - var validators = validationContext.ModelValidationContext.ValidatorProvider.GetValidators(elementMetadata); + var validatorProvider = validationContext.ModelValidationContext.ValidatorProvider; + var validatorProviderContext = new ModelValidatorProviderContext(elementMetadata); + validatorProvider.GetValidators(validatorProviderContext); + + var validators = validatorProviderContext.Validators; // If there are no validators or the object is null we bail out quickly // when there are large arrays of null, this will save a significant amount of processing @@ -220,20 +227,28 @@ namespace Microsoft.AspNet.Mvc.ModelBinding string modelKey, ModelExplorer modelExplorer, ValidationContext validationContext, - IEnumerable validators) + IList validators) { var isValid = true; + var modelState = validationContext.ModelValidationContext.ModelState; + var fieldValidationState = modelState.GetFieldValidationState(modelKey); + if (fieldValidationState == ModelValidationState.Invalid) + { + // Even if we have no validators it's possible that model binding may have added a + // validation error (conversion error, missing data). We want to still run + // validators even if that's the case. + isValid = false; + } + // When the are no validators we bail quickly. This saves a GetEnumerator allocation. // In a large array (tens of thousands or more) scenario it's very significant. - var validatorsAsCollection = validators as ICollection; - if (validatorsAsCollection == null || validatorsAsCollection.Count > 0) + if (validators == null || validators.Count > 0) { var modelValidationContext = new ModelValidationContext(validationContext.ModelValidationContext, modelExplorer); - var modelState = validationContext.ModelValidationContext.ModelState; + var modelValidationState = modelState.GetValidationState(modelKey); - var fieldValidationState = modelState.GetFieldValidationState(modelKey); // If either the model or its properties are unvalidated, validate them now. if (modelValidationState == ModelValidationState.Unvalidated || @@ -257,10 +272,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding } } } - else if (fieldValidationState == ModelValidationState.Invalid) - { - isValid = false; - } } if (isValid) diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IClientModelValidator.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IClientModelValidator.cs index aee9e004a1..86267444d0 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IClientModelValidator.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IClientModelValidator.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public interface IClientModelValidator { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ICompositeModelValidatorProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ICompositeModelValidatorProvider.cs index df13a6dad8..96497865cd 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ICompositeModelValidatorProvider.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ICompositeModelValidatorProvider.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { /// /// Represents aggregate of s that delegates to its underlying providers. diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IExcludeTypeValidationFilter.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IExcludeTypeValidationFilter.cs index 4348a03ff2..ed5b40ac89 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IExcludeTypeValidationFilter.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IExcludeTypeValidationFilter.cs @@ -4,7 +4,7 @@ using System; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { /// /// Provides an interface which is used to determine if s are excluded from model validation. diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IModelValidator.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IModelValidator.cs index 8f0994a85d..73722e3820 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IModelValidator.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IModelValidator.cs @@ -3,12 +3,26 @@ using System.Collections.Generic; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { + /// + /// Validates a model value. + /// public interface IModelValidator { + /// + /// Gets a value indicating whether or not this validator validates that a required value + /// has been provided for the model. + /// bool IsRequired { get; } + /// + /// Validates the model value. + /// + /// The . + /// + /// A list of indicating the results of validating the model value. + /// IEnumerable Validate(ModelValidationContext context); } } diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IModelValidatorProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IModelValidatorProvider.cs index 9a19d8faa3..4b082a2ed6 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IModelValidatorProvider.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IModelValidatorProvider.cs @@ -1,12 +1,21 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Collections.Generic; - -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { + /// + /// Provides validators for a model value. + /// public interface IModelValidatorProvider { - IEnumerable GetValidators(ModelMetadata metadata); + /// + /// Gets the validators for . + /// + /// The . + /// + /// Implementations should add instances to + /// . + /// + void GetValidators(ModelValidatorProviderContext context); } } diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IModelValidatorProviderProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IModelValidatorProviderProvider.cs index 5bac7b77e2..da0ebb9ba9 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IModelValidatorProviderProvider.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IModelValidatorProviderProvider.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { /// /// Provides an activated collection of instances. diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/IObjectModelValidator.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IObjectModelValidator.cs similarity index 92% rename from src/Microsoft.AspNet.Mvc.ModelBinding/IObjectModelValidator.cs rename to src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IObjectModelValidator.cs index e9f98e12c4..73db126a8b 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/IObjectModelValidator.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IObjectModelValidator.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { /// /// Provides methods to validate an object graph. diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IValidationExcludeFiltersProvider.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IValidationExcludeFiltersProvider.cs index 3e6e14fec5..8874a76cd9 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IValidationExcludeFiltersProvider.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/IValidationExcludeFiltersProvider.cs @@ -2,9 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; -using Microsoft.AspNet.Mvc.ModelBinding; -namespace Microsoft.AspNet.Mvc +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { /// /// Provides an activated collection of instances. diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/MaxLengthAttributeAdapter.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/MaxLengthAttributeAdapter.cs index 52fb005ef5..d777f8f2db 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/MaxLengthAttributeAdapter.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/MaxLengthAttributeAdapter.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class MaxLengthAttributeAdapter : DataAnnotationsModelValidator { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/MinLengthAttributeAdapter.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/MinLengthAttributeAdapter.cs index dabb4082a5..bf6fcca7f1 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/MinLengthAttributeAdapter.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/MinLengthAttributeAdapter.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class MinLengthAttributeAdapter : DataAnnotationsModelValidator { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationEqualToRule.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationEqualToRule.cs index f4593cd452..0197955ae2 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationEqualToRule.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationEqualToRule.cs @@ -3,7 +3,7 @@ using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { /// /// Represents client side validation rule that determines if two values are equal. diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationMaxLengthRule.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationMaxLengthRule.cs index 0d3508d27c..4dd800f2a8 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationMaxLengthRule.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationMaxLengthRule.cs @@ -3,7 +3,7 @@ using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class ModelClientValidationMaxLengthRule : ModelClientValidationRule { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationMinLengthRule.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationMinLengthRule.cs index 2cce428431..c100096efc 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationMinLengthRule.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationMinLengthRule.cs @@ -3,7 +3,7 @@ using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class ModelClientValidationMinLengthRule : ModelClientValidationRule { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRangeRule.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRangeRule.cs index a060c33d96..ccc15de163 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRangeRule.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRangeRule.cs @@ -3,7 +3,7 @@ using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class ModelClientValidationRangeRule : ModelClientValidationRule { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRegexRule.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRegexRule.cs index 89067c81ad..0e795cfff8 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRegexRule.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRegexRule.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class ModelClientValidationRegexRule : ModelClientValidationRule { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRequiredRule.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRequiredRule.cs index 8cc49d877e..8626c2a071 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRequiredRule.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRequiredRule.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class ModelClientValidationRequiredRule : ModelClientValidationRule { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRule.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRule.cs index 76e01a759d..71cf57d43f 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRule.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationRule.cs @@ -5,7 +5,7 @@ using System; using System.Collections.Generic; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class ModelClientValidationRule { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationStringLengthRule.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationStringLengthRule.cs index 4f8d3f6db8..8e728bbf9f 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationStringLengthRule.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelClientValidationStringLengthRule.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class ModelClientValidationStringLengthRule : ModelClientValidationRule { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelValiatorProviderContext.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelValiatorProviderContext.cs new file mode 100644 index 0000000000..a2a3830d66 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelValiatorProviderContext.cs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; + +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation +{ + /// + /// A context for . + /// + public class ModelValidatorProviderContext + { + /// + /// Creates a new . + /// + /// The . + public ModelValidatorProviderContext(ModelMetadata modelMetadata) + { + ModelMetadata = modelMetadata; + } + + /// + /// Gets the . + /// + public ModelMetadata ModelMetadata { get; } + + /// + /// Gets the validator metadata. + /// + /// + /// This property provides convenience access to . + /// + public IReadOnlyList ValidatorMetadata + { + get + { + return ModelMetadata.ValidatorMetadata; + } + } + + /// + /// Gets the list of instances. instances + /// should add validators to this list when + /// + /// is called. + /// + public IList Validators { get; } = new List(); + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelValidationContext.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelValidationContext.cs index be35ba033c..b93cea0ffd 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelValidationContext.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelValidationContext.cs @@ -1,10 +1,9 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Collections.Generic; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class ModelValidationContext { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelValidationResult.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelValidationResult.cs index 64459bea03..5ed1b0f5df 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelValidationResult.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ModelValidationResult.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class ModelValidationResult { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RangeAttributeAdapter.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RangeAttributeAdapter.cs index b669bb2c7e..b83cb2c7c9 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RangeAttributeAdapter.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RangeAttributeAdapter.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class RangeAttributeAdapter : DataAnnotationsModelValidator { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ReferenceEqualityComparer.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ReferenceEqualityComparer.cs index 9f3fd19edd..699552f2f1 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ReferenceEqualityComparer.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ReferenceEqualityComparer.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { internal class ReferenceEqualityComparer : IEqualityComparer { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RegularExpressionAttributeAdapter.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RegularExpressionAttributeAdapter.cs index 4ba165e5ea..094ff2feb3 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RegularExpressionAttributeAdapter.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RegularExpressionAttributeAdapter.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class RegularExpressionAttributeAdapter : DataAnnotationsModelValidator { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RequiredAttributeAdapter.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RequiredAttributeAdapter.cs index 9e1bf17e88..fb6940634f 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RequiredAttributeAdapter.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RequiredAttributeAdapter.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class RequiredAttributeAdapter : DataAnnotationsModelValidator { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RequiredMemberModelValidator.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RequiredMemberModelValidator.cs deleted file mode 100644 index 2b8bcac6e2..0000000000 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/RequiredMemberModelValidator.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Linq; - -namespace Microsoft.AspNet.Mvc.ModelBinding -{ - public class RequiredMemberModelValidator : IModelValidator - { - public bool IsRequired - { - get { return true; } - } - - public IEnumerable Validate(ModelValidationContext context) - { - return Enumerable.Empty(); - } - } -} diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/SimpleTypesExcludeFilter.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/SimpleTypesExcludeFilter.cs similarity index 97% rename from src/Microsoft.AspNet.Mvc.ModelBinding/SimpleTypesExcludeFilter.cs rename to src/Microsoft.AspNet.Mvc.ModelBinding/Validation/SimpleTypesExcludeFilter.cs index 84e31037ce..0d9a76c786 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/SimpleTypesExcludeFilter.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/SimpleTypesExcludeFilter.cs @@ -5,7 +5,7 @@ using System; using System.Collections.Generic; using System.Reflection; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { /// /// Identifies the simple types that the default model binding validation will exclude. diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/StringLengthAttributeAdapter.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/StringLengthAttributeAdapter.cs index 5b151e3acf..dc18c738d2 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/StringLengthAttributeAdapter.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/StringLengthAttributeAdapter.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using Microsoft.Framework.Internal; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class StringLengthAttributeAdapter : DataAnnotationsModelValidator { diff --git a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ValidatableObjectAdapter.cs b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ValidatableObjectAdapter.cs index 0f99b90ce1..9da152887c 100644 --- a/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ValidatableObjectAdapter.cs +++ b/src/Microsoft.AspNet.Mvc.ModelBinding/Validation/ValidatableObjectAdapter.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class ValidatableObjectAdapter : IModelValidator { diff --git a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ApiController.cs b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ApiController.cs index 6ae87ee318..b80688de9a 100644 --- a/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ApiController.cs +++ b/src/Microsoft.AspNet.Mvc.WebApiCompatShim/ApiController.cs @@ -8,8 +8,8 @@ using System.Text; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.WebApiCompatShim; -using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; using Newtonsoft.Json; diff --git a/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs b/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs index 2b642ea8cd..5a228295dc 100644 --- a/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs +++ b/src/Microsoft.AspNet.Mvc/MvcOptionsSetup.cs @@ -5,6 +5,7 @@ using System; using System.Xml.Linq; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding.Metadata; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.Razor; using Microsoft.Framework.OptionsModel; using Microsoft.Net.Http.Headers; @@ -62,11 +63,13 @@ namespace Microsoft.AspNet.Mvc // Set up metadata providers options.ModelMetadataDetailsProviders.Add(new DefaultBindingMetadataProvider()); - options.ModelMetadataDetailsProviders.Add(new DataAnnotationsMetadataDetailsProvider()); + options.ModelMetadataDetailsProviders.Add(new DefaultValidationMetadataProvider()); + options.ModelMetadataDetailsProviders.Add(new DataAnnotationsMetadataProvider()); + options.ModelMetadataDetailsProviders.Add(new DataMemberRequiredValidationMetadataProvider()); // Set up validators + options.ModelValidatorProviders.Add(new DefaultModelValidatorProvider()); options.ModelValidatorProviders.Add(new DataAnnotationsModelValidatorProvider()); - options.ModelValidatorProviders.Add(new DataMemberModelValidatorProvider()); // Add types to be excluded from Validation options.ValidationExcludeFilters.Add(new SimpleTypesExcludeFilter()); diff --git a/src/Microsoft.AspNet.Mvc/MvcServices.cs b/src/Microsoft.AspNet.Mvc/MvcServices.cs index 08f691871c..f14ad95f8a 100644 --- a/src/Microsoft.AspNet.Mvc/MvcServices.cs +++ b/src/Microsoft.AspNet.Mvc/MvcServices.cs @@ -9,6 +9,7 @@ using Microsoft.AspNet.Mvc.Filters; using Microsoft.AspNet.Mvc.Internal; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding.Metadata; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.OptionDescriptors; using Microsoft.AspNet.Mvc.Razor; using Microsoft.AspNet.Mvc.Razor.Directives; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/BodyModelBinderTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/BodyModelBinderTests.cs index 7b6f477e8e..1cbcfb3762 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/BodyModelBinderTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/BodyModelBinderTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Linq; using System.Collections.Generic; using System.IO; using System.Text; @@ -10,8 +9,8 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Core; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Routing; -using Microsoft.Framework.DependencyInjection; using Microsoft.Net.Http.Headers; using Moq; using Xunit; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerActionInvokerTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerActionInvokerTest.cs index 02993b33c3..cca14ad33a 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerActionInvokerTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerActionInvokerTest.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Reflection; @@ -13,9 +12,9 @@ using Microsoft.AspNet.Http.Core; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding.Metadata; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Routing; using Microsoft.AspNet.Testing; -using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.OptionsModel; using Moq; using Xunit; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs index 662f0b231d..b92c3a665c 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs @@ -12,6 +12,7 @@ using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Core; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Routing; using Microsoft.AspNet.Testing; using Microsoft.AspNet.WebUtilities; @@ -1580,8 +1581,8 @@ namespace Microsoft.AspNet.Mvc.Test .Returns(validationResult); var provider = new Mock(); - provider.Setup(v => v.GetValidators(It.IsAny())) - .Returns(new[] { validator1.Object }); + provider.Setup(v => v.GetValidators(It.IsAny())) + .Callback(c => c.Validators.Add(validator1.Object)); var binder = new Mock(); var controller = GetController(binder.Object, provider: null); @@ -1613,8 +1614,8 @@ namespace Microsoft.AspNet.Mvc.Test .Returns(validationResult); var provider = new Mock(); - provider.Setup(v => v.GetValidators(It.IsAny())) - .Returns(new[] { validator1.Object }); + provider.Setup(v => v.GetValidators(It.IsAny())) + .Callback(c => c.Validators.Add(validator1.Object)); var binder = new Mock(); var controller = GetController(binder.Object, provider: null); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerFactoryTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerFactoryTest.cs index 6f222a2037..50b458c603 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerFactoryTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultControllerFactoryTest.cs @@ -6,6 +6,7 @@ using System.Reflection; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Core; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Routing; using Microsoft.Framework.DependencyInjection; using Moq; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/MockModelValidatorProviderProvider.cs b/test/Microsoft.AspNet.Mvc.Core.Test/MockModelValidatorProviderProvider.cs index 8c9b8612df..bd7877b13b 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/MockModelValidatorProviderProvider.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/MockModelValidatorProviderProvider.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { - public class MockModelValidatorProviderProvider: IModelValidatorProviderProvider + public class MockModelValidatorProviderProvider : IModelValidatorProviderProvider { public List ModelValidatorProviders { get; } = new List(); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/DefaultValidationProviderProviderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/DefaultValidationProviderProviderTest.cs index af31c9f994..c8c8f021ce 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/DefaultValidationProviderProviderTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/DefaultValidationProviderProviderTest.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Framework.OptionsModel; using Moq; using Xunit; @@ -52,9 +53,8 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors public ITestService Service { get; private set; } - public IEnumerable GetValidators(ModelMetadata metadata) + public void GetValidators(ModelValidatorProviderContext context) { - throw new NotImplementedException(); } } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/ExcludeValidationDescriptorTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/ExcludeValidationDescriptorTests.cs index db872c7b50..aa7bd538ea 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/ExcludeValidationDescriptorTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/ExcludeValidationDescriptorTests.cs @@ -2,7 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Testing; using Microsoft.Framework.Internal; using Xunit; @@ -16,7 +16,7 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors { // Arrange var expected = "The type 'System.String' must derive from " + - "'Microsoft.AspNet.Mvc.ModelBinding.IExcludeTypeValidationFilter'."; + "'Microsoft.AspNet.Mvc.ModelBinding.Validation.IExcludeTypeValidationFilter'."; var type = typeof(string); // Act & Assert diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/ModelValidatorProviderDescriptor.cs b/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/ModelValidatorProviderDescriptor.cs index 34c583dd3a..ad335b9247 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/ModelValidatorProviderDescriptor.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/ModelValidatorProviderDescriptor.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Testing; using Xunit; @@ -54,9 +55,8 @@ namespace Microsoft.AspNet.Mvc.OptionDescriptors private class TestModelValidatorProvider : IModelValidatorProvider { - public IEnumerable GetValidators(ModelMetadata metadata) + public void GetValidators(ModelValidatorProviderContext context) { - throw new NotImplementedException(); } } } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/ModelValidatorProviderDescriptorExtensionsTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/ModelValidatorProviderDescriptorExtensionsTest.cs index c89752ff33..882116f31b 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/ModelValidatorProviderDescriptorExtensionsTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/OptionDescriptors/ModelValidatorProviderDescriptorExtensionsTest.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.OptionDescriptors; using Moq; using Xunit; @@ -52,7 +53,7 @@ namespace Microsoft.AspNet.Mvc // Arrange var provider1 = Mock.Of(); var provider2 = Mock.Of(); - var type1 = typeof(DataMemberModelValidatorProvider); + var type1 = typeof(DefaultModelValidatorProvider); var type2 = typeof(DataAnnotationsModelValidatorProvider); var collection = new List(); @@ -66,7 +67,7 @@ namespace Microsoft.AspNet.Mvc Assert.Equal(4, collection.Count); Assert.Same(provider1, collection[0].Instance); Assert.Same(provider2, collection[1].Instance); - Assert.IsType(collection[2].OptionType); + Assert.IsType(collection[2].OptionType); Assert.IsType(collection[3].OptionType); } } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ParameterBinding/ControllerActionArgumentBinderTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ParameterBinding/ControllerActionArgumentBinderTests.cs index 0c8b04b043..114b58e656 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ParameterBinding/ControllerActionArgumentBinderTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ParameterBinding/ControllerActionArgumentBinderTests.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http.Core; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding.Metadata; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Routing; using Moq; using Xunit; @@ -416,4 +417,4 @@ namespace Microsoft.AspNet.Mvc.Core.Test public int IncludedExplicitly2 { get; set; } } } -} \ No newline at end of file +} diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ParameterBinding/ModelBindingHelperTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ParameterBinding/ModelBindingHelperTest.cs index 32d474f71f..d09711de9b 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ParameterBinding/ModelBindingHelperTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ParameterBinding/ModelBindingHelperTest.cs @@ -3,20 +3,18 @@ #if DNX451 using System; -using System.Collections; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.Linq; using System.Linq.Expressions; -using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Testing; using Moq; using Xunit; -namespace Microsoft.AspNet.Mvc.Core.Test +namespace Microsoft.AspNet.Mvc.Test { public class ModelBindingHelperTest { diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/RemoteAttributeTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/RemoteAttributeTest.cs index bd7b4aae7e..6117032608 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/RemoteAttributeTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/RemoteAttributeTest.cs @@ -2,10 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Collections.Generic; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http.Core; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Routing; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Logging; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTest.cs index 3f70d7e464..467d9ab9c5 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTest.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Testing; using Microsoft.Framework.Internal; diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs index ac9991a245..4f2962afab 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultTemplatesUtilities.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Http.Core; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Routing; using Microsoft.Framework.OptionsModel; using Microsoft.Framework.WebEncoders; diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/BinderTypeBasedModelBinderModelBinderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/BinderTypeBasedModelBinderModelBinderTest.cs index 45beefa362..435d5596cc 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/BinderTypeBasedModelBinderModelBinderTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/BinderTypeBasedModelBinderModelBinderTest.cs @@ -6,9 +6,10 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNet.Http.Core; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; +using Microsoft.Framework.DependencyInjection; using Moq; using Xunit; -using Microsoft.Framework.DependencyInjection; namespace Microsoft.AspNet.Mvc.ModelBinding.Test { diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/CompositeModelBinderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/CompositeModelBinderTest.cs index 5fc3692480..f36e6ee137 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/CompositeModelBinderTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/CompositeModelBinderTest.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Moq; using Xunit; @@ -461,8 +462,20 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test private static IModelValidatorProvider GetValidatorProvider(params IModelValidator[] validators) { var provider = new Mock(); - provider.Setup(v => v.GetValidators(It.IsAny())) - .Returns(validators ?? Enumerable.Empty()); + provider + .Setup(v => v.GetValidators(It.IsAny())) + .Callback(c => + { + if (validators == null) + { + return; + } + + foreach (var validator in validators) + { + c.Validators.Add(validator); + } + }); return provider.Object; } diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/KeyValuePairModelBinderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/KeyValuePairModelBinderTest.cs index 4335ec30c9..9655ef8a40 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/KeyValuePairModelBinderTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/KeyValuePairModelBinderTest.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Moq; using Xunit; diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/MutableObjectModelBinderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/MutableObjectModelBinderTest.cs index 4039322c45..20f6599def 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/MutableObjectModelBinderTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Binders/MutableObjectModelBinderTest.cs @@ -9,6 +9,7 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNet.Http.Core; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Testing; using Moq; using Xunit; @@ -1194,10 +1195,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding isModelSet: false, key: "foo"); - var requiredValidator = bindingContext.OperationBindingContext - .ValidatorProvider - .GetValidators(propertyMetadata) - .FirstOrDefault(v => v.IsRequired); + var validatorProvider = bindingContext.OperationBindingContext.ValidatorProvider; + var validatorProviderContext = new ModelValidatorProviderContext(propertyMetadata); + validatorProvider.GetValidators(validatorProviderContext); + + var requiredValidator = validatorProviderContext.Validators.FirstOrDefault(v => v.IsRequired); var testableBinder = new TestableMutableObjectModelBinder(); @@ -1327,11 +1329,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding key: "foo", isModelSet: true); + var validatorProvider = bindingContext.OperationBindingContext.ValidatorProvider; + var validatorProviderContext = new ModelValidatorProviderContext(propertyMetadata); + validatorProvider.GetValidators(validatorProviderContext); - var requiredValidator = bindingContext.OperationBindingContext - .ValidatorProvider - .GetValidators(propertyMetadata) - .FirstOrDefault(v => v.IsRequired); + var requiredValidator = validatorProviderContext.Validators.FirstOrDefault(v => v.IsRequired); var testableBinder = new TestableMutableObjectModelBinder(); @@ -1526,12 +1528,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding private static ModelBindingContext CreateContext(ModelMetadata metadata, object model) { - var providers = new IModelValidatorProvider[] - { - new DataAnnotationsModelValidatorProvider(), - new DataMemberModelValidatorProvider() - }; - return new ModelBindingContext { Model = model, @@ -1541,17 +1537,18 @@ namespace Microsoft.AspNet.Mvc.ModelBinding OperationBindingContext = new OperationBindingContext { MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(), - ValidatorProvider = new CompositeModelValidatorProvider(providers) + ValidatorProvider = TestModelValidatorProvider.CreateDefaultProvider(), } }; } private static IModelValidator GetRequiredValidator(ModelBindingContext bindingContext, ModelMetadata propertyMetadata) { - return bindingContext.OperationBindingContext - .ValidatorProvider - .GetValidators(propertyMetadata) - .FirstOrDefault(v => v.IsRequired); + var validatorProvider = bindingContext.OperationBindingContext.ValidatorProvider; + var validatorProviderContext = new ModelValidatorProviderContext(propertyMetadata); + validatorProvider.GetValidators(validatorProviderContext); + + return validatorProviderContext.Validators.FirstOrDefault(v => v.IsRequired); } private static ModelMetadata GetMetadataForCanUpdateProperty(string propertyName) diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DataAnnotationsMetadataDetailsProviderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DataAnnotationsMetadataProviderTest.cs similarity index 92% rename from test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DataAnnotationsMetadataDetailsProviderTest.cs rename to test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DataAnnotationsMetadataProviderTest.cs index 8d567a3f13..f684f7164e 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DataAnnotationsMetadataDetailsProviderTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DataAnnotationsMetadataProviderTest.cs @@ -7,7 +7,7 @@ using Xunit; namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata { - public class DataAnnotationsMetadataDetailsProviderTest + public class DataAnnotationsMetadataProviderTest { // Includes attributes with a 'simple' effect on display details. public static TheoryData, object> DisplayDetailsData @@ -52,7 +52,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata object expected) { // Arrange - var provider = new DataAnnotationsMetadataDetailsProvider(); + var provider = new DataAnnotationsMetadataProvider(); var key = ModelMetadataIdentity.ForType(typeof(string)); var context = new DisplayMetadataProviderContext(key, new object[] { attribute }); @@ -69,7 +69,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata public void GetDisplayDetails_FindsDisplayFormat_FromDataType() { // Arrange - var provider = new DataAnnotationsMetadataDetailsProvider(); + var provider = new DataAnnotationsMetadataProvider(); var dataType = new DataTypeAttribute(DataType.Currency); var displayFormat = dataType.DisplayFormat; // Non-null for DataType.Currency. @@ -89,7 +89,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata public void GetDisplayDetails_FindsDisplayFormat_OverridingDataType() { // Arrange - var provider = new DataAnnotationsMetadataDetailsProvider(); + var provider = new DataAnnotationsMetadataProvider(); var dataType = new DataTypeAttribute(DataType.Time); // Has a non-null DisplayFormat. var displayFormat = new DisplayFormatAttribute() // But these values override the values from DataType @@ -112,7 +112,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata public void GetDisplayDetails_EditableAttribute_SetsReadOnly() { // Arrange - var provider = new DataAnnotationsMetadataDetailsProvider(); + var provider = new DataAnnotationsMetadataProvider(); var editable = new EditableAttribute(allowEdit: false); @@ -131,7 +131,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata public void GetDisplayDetails_RequiredAttribute_SetsRequired() { // Arrange - var provider = new DataAnnotationsMetadataDetailsProvider(); + var provider = new DataAnnotationsMetadataProvider(); var required = new RequiredAttribute(); @@ -151,7 +151,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata public void GetDisplayDetails_DisplayAttribute_NameFromResources() { // Arrange - var provider = new DataAnnotationsMetadataDetailsProvider(); + var provider = new DataAnnotationsMetadataProvider(); var display = new DisplayAttribute() { @@ -175,7 +175,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata public void GetDisplayDetails_DisplayAttribute_DescriptionFromResources() { // Arrange - var provider = new DataAnnotationsMetadataDetailsProvider(); + var provider = new DataAnnotationsMetadataProvider(); var display = new DisplayAttribute() { diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DataMemberBindingMetadataProviderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DataMemberBindingMetadataProviderTest.cs new file mode 100644 index 0000000000..8c41a59c31 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DataMemberBindingMetadataProviderTest.cs @@ -0,0 +1,96 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Runtime.Serialization; +using Xunit; + +namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata +{ + public class DataMemberBindingMetadataProviderTest + { + [Fact] + public void ClassWithoutAttributes_NotRequired() + { + // Arrange + var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + + // Act + var metadata = metadataProvider.GetMetadataForProperty( + typeof(ClassWithoutAttributes), + "TheProperty"); + + // Assert + Assert.False(metadata.IsRequired); + } + + private class ClassWithoutAttributes + { + public string TheProperty { get; set; } + } + + [Fact] + public void ClassWithDataMemberIsRequiredTrue_Validator() + { + // Arrange + var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + + // Act + var metadata = metadataProvider.GetMetadataForProperty( + typeof(ClassWithDataMemberIsRequiredTrue), + "TheProperty"); + + // Assert + Assert.True(metadata.IsRequired); + } + + [DataContract] + private class ClassWithDataMemberIsRequiredTrue + { + [DataMember(IsRequired = true)] + public string TheProperty { get; set; } + } + + [Fact] + public void ClassWithDataMemberIsRequiredFalse_NoValidator() + { + // Arrange + var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + + // Act + var metadata = metadataProvider.GetMetadataForProperty( + typeof(ClassWithDataMemberIsRequiredFalse), + "TheProperty"); + + // Assert + Assert.False(metadata.IsRequired); + } + + [DataContract] + private class ClassWithDataMemberIsRequiredFalse + { + [DataMember(IsRequired = false)] + public int TheProperty { get; set; } + } + + [Fact] + public void ClassWithDataMemberIsRequiredTrueWithoutDataContract_NoValidator() + { + // Arrange + var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + + // Act + var metadata = metadataProvider.GetMetadataForProperty( + typeof(ClassWithDataMemberIsRequiredTrueWithoutDataContract), + "TheProperty"); + + // Assert + Assert.False(metadata.IsRequired); + } + + private class ClassWithDataMemberIsRequiredTrueWithoutDataContract + { + [DataMember(IsRequired = true)] + public int TheProperty { get; set; } + } + } +} diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DefaultModelMetadataProviderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DefaultModelMetadataProviderTest.cs index 24fc89db0b..885a096849 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DefaultModelMetadataProviderTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DefaultModelMetadataProviderTest.cs @@ -110,6 +110,20 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata Assert.Equal("OnPropertyType", Assert.IsType(attributes[1]).Value); } + [Fact] + public void GetMetadataForProperties_ExcludesHiddenProperties() + { + // Arrange + var provider = CreateProvider(); + + // Act + var metadata = provider.GetMetadataForProperties(typeof(DerivedModelWithHiding)); + + // Assert + var propertyMetadata = Assert.Single(metadata); + Assert.Equal(typeof(string), propertyMetadata.ModelType); + } + private static DefaultModelMetadataProvider CreateProvider() { return new DefaultModelMetadataProvider(new EmptyCompositeMetadataDetailsProvider()); @@ -149,5 +163,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata private void GetMetadataForParameterTestMethod([Model("OnParameter")] ModelType parameter) { } + + private class BaseModelWithHiding + { + public int Property { get; set; } + } + + private class DerivedModelWithHiding : BaseModelWithHiding + { + public new string Property { get; set; } + } } -} \ No newline at end of file +} diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataProviderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataProviderTest.cs index 5f11ea44c3..91ebb4e296 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataProviderTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataProviderTest.cs @@ -701,7 +701,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata : base(new DefaultCompositeMetadataDetailsProvider(new IMetadataDetailsProvider[] { new DefaultBindingMetadataProvider(), - new DataAnnotationsMetadataDetailsProvider(), + new DataAnnotationsMetadataProvider(), })) { _attributes = attributes; diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataTest.cs index 0c4b72aee3..4da7aaf73b 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/ModelMetadataTest.cs @@ -372,6 +372,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding throw new NotImplementedException(); } } + + public override IReadOnlyList ValidatorMetadata + { + get + { + throw new NotImplementedException(); + } + } } } } diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/SimpleTypeExcludeFilterTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/SimpleTypeExcludeFilterTest.cs index 5918bc629d..e697585708 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/SimpleTypeExcludeFilterTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/SimpleTypeExcludeFilterTest.cs @@ -5,7 +5,7 @@ using System; using System.Collections.Generic; using Xunit; -namespace Microsoft.AspNet.Mvc.ModelBinding.Test +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class SimpleTypeExcluceFilterTest { diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/AssociatedValidatorProviderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/AssociatedValidatorProviderTest.cs deleted file mode 100644 index 35a9d52fcc..0000000000 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/AssociatedValidatorProviderTest.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#if DNX451 -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using Moq; -using Xunit; - -namespace Microsoft.AspNet.Mvc.ModelBinding -{ - public class AssociatedValidatorProviderTest - { - private readonly IModelMetadataProvider _metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); - - [Fact] - public void GetValidatorsForPropertyWithLocalAttributes() - { - // Arrange - IEnumerable callbackAttributes = null; - var metadata = _metadataProvider.GetMetadataForProperty(typeof(PropertyModel), "LocalAttributes"); - var provider = new Mock { CallBase = true }; - provider.Setup(p => p.AbstractGetValidators(metadata, It.IsAny>())) - .Callback>((m, attributes) => callbackAttributes = attributes) - .Returns((IEnumerable)null) - .Verifiable(); - - // Act - provider.Object.GetValidators(metadata); - - // Assert - provider.Verify(); - Assert.True(callbackAttributes.Any(a => a is RequiredAttribute)); - } - - [Fact] - public void GetValidatorsForPropertyWithMetadataAttributes() - { - // Arrange - IEnumerable callbackAttributes = null; - var metadata = _metadataProvider.GetMetadataForProperty(typeof(PropertyModel), "MetadataAttributes"); - var provider = new Mock { CallBase = true }; - provider.Setup(p => p.AbstractGetValidators(metadata, It.IsAny>())) - .Callback>((m, attributes) => callbackAttributes = attributes) - .Returns((IEnumerable)null) - .Verifiable(); - - // Act - provider.Object.GetValidators(metadata); - - // Assert - provider.Verify(); - Assert.True(callbackAttributes.Any(a => a is RangeAttribute)); - } - - [Fact] - public void GetValidatorsForPropertyWithMixedAttributes() - { - // Arrange - IEnumerable callbackAttributes = null; - var metadata = _metadataProvider.GetMetadataForProperty(typeof(PropertyModel), "MixedAttributes"); - var provider = new Mock { CallBase = true }; - provider.Setup(p => p.AbstractGetValidators(metadata, It.IsAny>())) - .Callback>((m, attributes) => callbackAttributes = attributes) - .Returns((IEnumerable)null) - .Verifiable(); - - // Act - provider.Object.GetValidators(metadata); - - // Assert - provider.Verify(); - Assert.True(callbackAttributes.Any(a => a is RangeAttribute)); - Assert.True(callbackAttributes.Any(a => a is RequiredAttribute)); - } - - private class PropertyModel - { - [Required] - public int LocalAttributes { get; set; } - - [Range(10, 100)] - public string MetadataAttributes { get; set; } - - [Required] - [Range(10, 100)] - public double MixedAttributes { get; set; } - } - - public abstract class TestableAssociatedValidatorProvider : AssociatedValidatorProvider - { - protected override IEnumerable GetValidators(ModelMetadata metadata, IEnumerable attributes) - { - return AbstractGetValidators(metadata, attributes); - } - - public abstract IEnumerable AbstractGetValidators(ModelMetadata metadata, IEnumerable attributes); - } - } -} -#endif diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/CompareAttributeAdapterTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/CompareAttributeAdapterTest.cs index 0a0d647084..40b3447211 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/CompareAttributeAdapterTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/CompareAttributeAdapterTest.cs @@ -6,7 +6,7 @@ using Microsoft.AspNet.Testing; using Microsoft.Framework.DependencyInjection; using Xunit; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class CompareAttributeAdapterTest { diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/CompositeModelValidatorProviderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/CompositeModelValidatorProviderTest.cs index 4132b0194f..b500d1faf5 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/CompositeModelValidatorProviderTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/CompositeModelValidatorProviderTest.cs @@ -2,10 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. #if DNX451 +using System.Linq; using Moq; using Xunit; -namespace Microsoft.AspNet.Mvc.ModelBinding.Test +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class CompositeModelValidatorProviderTest { @@ -16,20 +17,33 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test var validator1 = Mock.Of(); var validator2 = Mock.Of(); var validator3 = Mock.Of(); + var provider1 = new Mock(); - provider1.Setup(p => p.GetValidators(It.IsAny())) - .Returns(new[] { validator1, validator2 }); + provider1.Setup(p => p.GetValidators(It.IsAny())) + .Callback(c => + { + c.Validators.Add(validator1); + c.Validators.Add(validator2); + }); + var provider2 = new Mock(); - provider2.Setup(p => p.GetValidators(It.IsAny())) - .Returns(new[] { validator3 }); + provider2.Setup(p => p.GetValidators(It.IsAny())) + .Callback(c => + { + c.Validators.Add(validator3); + }); + var compositeModelValidator = new CompositeModelValidatorProvider(new[] { provider1.Object, provider2.Object }); var modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(string)); // Act - var result = compositeModelValidator.GetValidators(modelMetadata); + var validatorProviderContext = new ModelValidatorProviderContext(modelMetadata); + compositeModelValidator.GetValidators(validatorProviderContext); // Assert - Assert.Equal(new[] { validator1, validator2, validator3 }, result); + Assert.Equal( + new[] { validator1, validator2, validator3 }, + validatorProviderContext.Validators.ToArray()); } } } diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DataAnnotationsModelValidatorProviderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DataAnnotationsModelValidatorProviderTest.cs index 344dec6052..47bc1184ac 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DataAnnotationsModelValidatorProviderTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DataAnnotationsModelValidatorProviderTest.cs @@ -10,7 +10,7 @@ using Moq; #endif using Xunit; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class DataAnnotationsModelValidatorProviderTest { @@ -25,11 +25,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var mockValidatable = Mock.Of(); var metadata = _metadataProvider.GetMetadataForType(mockValidatable.GetType()); + var providerContext = new ModelValidatorProviderContext(metadata); + // Act - var validators = provider.GetValidators(metadata); + provider.GetValidators(providerContext); // Assert - var validator = Assert.Single(validators); + var validator = Assert.Single(providerContext.Validators); Assert.IsType(validator); } #endif @@ -42,11 +44,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var metadata = _metadataProvider.GetMetadataForProperty(typeof(DummyRequiredAttributeHelperClass), "WithAttribute"); + var providerContext = new ModelValidatorProviderContext(metadata); + // Act - var validators = provider.GetValidators(metadata); + provider.GetValidators(providerContext); // Assert - var validator = Assert.Single(validators); + var validator = Assert.Single(providerContext.Validators); var adapter = Assert.IsType(validator); Assert.Equal("Custom Required Message", adapter.Attribute.ErrorMessage); } @@ -144,11 +148,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var provider = new DataAnnotationsModelValidatorProvider(); var metadata = _metadataProvider.GetMetadataForType(typeof(DummyClassWithDummyValidationAttribute)); + var providerContext = new ModelValidatorProviderContext(metadata); + // Act - IEnumerable validators = provider.GetValidators(metadata); + provider.GetValidators(providerContext); // Assert - var validator = validators.Single(); + var validator = providerContext.Validators.Single(); Assert.IsType(validator); } @@ -172,42 +178,16 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var mockValidatable = new Mock(); var metadata = _metadataProvider.GetMetadataForType(mockValidatable.Object.GetType()); + var providerContext = new ModelValidatorProviderContext(metadata); + // Act - var validators = provider.GetValidators(metadata); + provider.GetValidators(providerContext); // Assert - Assert.Single(validators); + Assert.Single(providerContext.Validators); } #endif - // Integration with metadata system - - [Fact] - public void DoesNotReadPropertyValue() - { - // Arrange - var provider = new DataAnnotationsModelValidatorProvider(); - var model = new ObservableModel(); - - var modelExplorer = _metadataProvider - .GetModelExplorerForType(typeof(ObservableModel), model) - .GetExplorerForProperty("TheProperty"); - - var context = new ModelValidationContext( - rootPrefix: null, - validatorProvider: null, - modelState: null, - modelExplorer: modelExplorer); - - // Act - var validators = provider.GetValidators(modelExplorer.Metadata).ToArray(); - var results = validators.SelectMany(o => o.Validate(context)).ToArray(); - - // Assert - Assert.Empty(validators); - Assert.False(model.PropertyWasRead()); - } - private class ObservableModel { private bool _propertyWasRead; diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DataAnnotationsModelValidatorTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DataAnnotationsModelValidatorTest.cs index 61b8bd1508..7a594ea85e 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DataAnnotationsModelValidatorTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DataAnnotationsModelValidatorTest.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; #if DNX451 @@ -14,7 +13,7 @@ using Moq.Protected; #endif using Xunit; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class DataAnnotationsModelValidatorTest { diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DataMemberModelValidatorProviderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DataMemberModelValidatorProviderTest.cs deleted file mode 100644 index 96af57fe73..0000000000 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DataMemberModelValidatorProviderTest.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Runtime.Serialization; -using Xunit; - -namespace Microsoft.AspNet.Mvc.ModelBinding -{ - public class DataMemberModelValidatorProviderTest - { - private readonly IModelMetadataProvider _metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); - - [Fact] - public void ClassWithoutAttributes_NoValidator() - { - // Arrange - var provider = new DataMemberModelValidatorProvider(); - var metadata = _metadataProvider.GetMetadataForProperty(typeof(ClassWithoutAttributes), "TheProperty"); - - // Act - var validators = provider.GetValidators(metadata); - - // Assert - Assert.Empty(validators); - } - - private class ClassWithoutAttributes - { - public int TheProperty { get; set; } - } - - [Fact] - public void ClassWithDataMemberIsRequiredTrue_Validator() - { - // Arrange - var provider = new DataMemberModelValidatorProvider(); - var metadata = _metadataProvider.GetMetadataForProperty(typeof(ClassWithDataMemberIsRequiredTrue), "TheProperty"); - - // Act - var validators = provider.GetValidators(metadata); - - // Assert - var validator = Assert.Single(validators); - Assert.True(validator.IsRequired); - } - - [DataContract] - private class ClassWithDataMemberIsRequiredTrue - { - [DataMember(IsRequired = true)] - public int TheProperty { get; set; } - } - - [Fact] - public void ClassWithDataMemberIsRequiredFalse_NoValidator() - { - // Arrange - var provider = new DataMemberModelValidatorProvider(); - var metadata = _metadataProvider.GetMetadataForProperty(typeof(ClassWithDataMemberIsRequiredFalse), "TheProperty"); - - // Act - var validators = provider.GetValidators(metadata); - - // Assert - Assert.Empty(validators); - } - - [DataContract] - private class ClassWithDataMemberIsRequiredFalse - { - [DataMember(IsRequired = false)] - public int TheProperty { get; set; } - } - - [Fact] - public void ClassWithDataMemberIsRequiredTrueWithoutDataContract_NoValidator() - { - // Arrange - var provider = new DataMemberModelValidatorProvider(); - var metadata = _metadataProvider.GetMetadataForProperty(typeof(ClassWithDataMemberIsRequiredTrueWithoutDataContract), "TheProperty"); - - // Act - var validators = provider.GetValidators(metadata); - - // Assert - Assert.Empty(validators); - } - - private class ClassWithDataMemberIsRequiredTrueWithoutDataContract - { - [DataMember(IsRequired = true)] - public int TheProperty { get; set; } - } - } -} diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DefaultModelValidatorProviderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DefaultModelValidatorProviderTest.cs new file mode 100644 index 0000000000..cdab98fcdb --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DefaultModelValidatorProviderTest.cs @@ -0,0 +1,264 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using Xunit; + +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation +{ + // Integration tests for the default configuration of ModelMetadata and Validation providers + public class DefaultModelValidatorProviderTest + { + [Fact] + public void GetValidators_ForIValidatableObject() + { + // Arrange + var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var validatorProvider = TestModelValidatorProvider.CreateDefaultProvider(); + + var metadata = metadataProvider.GetMetadataForType(typeof(ValidatableObject)); + var context = new ModelValidatorProviderContext(metadata); + + // Act + validatorProvider.GetValidators(context); + + // Assert + var validators = context.Validators; + + var validator = Assert.Single(validators); + Assert.IsType(validator); + } + + [Fact] + public void GetValidators_ModelValidatorAttributeOnClass() + { + // Arrange + var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var validatorProvider = TestModelValidatorProvider.CreateDefaultProvider(); + + var metadata = metadataProvider.GetMetadataForType(typeof(ModelValidatorAttributeOnClass)); + var context = new ModelValidatorProviderContext(metadata); + + // Act + validatorProvider.GetValidators(context); + + // Assert + var validators = context.Validators; + + var validator = Assert.IsType(Assert.Single(validators)); + Assert.Equal("Class", validator.Tag); + } + + [Fact] + public void GetValidators_ModelValidatorAttributeOnProperty() + { + // Arrange + var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var validatorProvider = TestModelValidatorProvider.CreateDefaultProvider(); + + var metadata = metadataProvider.GetMetadataForProperty( + typeof(ModelValidatorAttributeOnProperty), + nameof(ModelValidatorAttributeOnProperty.Property)); + var context = new ModelValidatorProviderContext(metadata); + + // Act + validatorProvider.GetValidators(context); + + // Assert + var validators = context.Validators; + + var validator = Assert.IsType(Assert.Single(validators)); + Assert.Equal("Property", validator.Tag); + } + + [Fact] + public void GetValidators_ModelValidatorAttributeOnPropertyAndClass() + { + // Arrange + var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var validatorProvider = TestModelValidatorProvider.CreateDefaultProvider(); + + var metadata = metadataProvider.GetMetadataForProperty( + typeof(ModelValidatorAttributeOnPropertyAndClass), + nameof(ModelValidatorAttributeOnPropertyAndClass.Property)); + var context = new ModelValidatorProviderContext(metadata); + + // Act + validatorProvider.GetValidators(context); + + // Assert + var validators = context.Validators; + + Assert.Equal(2, validators.Count); + Assert.Single(validators, v => Assert.IsType(v).Tag == "Class"); + Assert.Single(validators, v => Assert.IsType(v).Tag == "Property"); + } + + // RangeAttribute is an example of a ValidationAttribute with it's own adapter type. + [Fact] + public void GetValidators_DataAnnotationsAttribute_SpecificAdapter() + { + // Arrange + var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var validatorProvider = TestModelValidatorProvider.CreateDefaultProvider(); + + var metadata = metadataProvider.GetMetadataForProperty( + typeof(RangeAttributeOnProperty), + nameof(RangeAttributeOnProperty.Property)); + var context = new ModelValidatorProviderContext(metadata); + + // Act + validatorProvider.GetValidators(context); + + // Assert + var validators = context.Validators; + + Assert.IsType(Assert.Single(validators)); + } + + [Fact] + public void GetValidators_DataAnnotationsAttribute_DefaultAdapter() + { + // Arrange + var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var validatorProvider = TestModelValidatorProvider.CreateDefaultProvider(); + + var metadata = metadataProvider.GetMetadataForProperty( + typeof(CustomValidationAttributeOnProperty), + nameof(CustomValidationAttributeOnProperty.Property)); + var context = new ModelValidatorProviderContext(metadata); + + // Act + validatorProvider.GetValidators(context); + + // Assert + var validators = context.Validators; + + Assert.IsType(Assert.Single(validators)); + } + + [Fact] + public void GetValidators_FromModelMetadataType_SingleValidator() + { + // Arrange + var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var validatorProvider = TestModelValidatorProvider.CreateDefaultProvider(); + + var metadata = metadataProvider.GetMetadataForProperty( + typeof(ProductViewModel), + nameof(ProductViewModel.Id)); + var context = new ModelValidatorProviderContext(metadata); + + // Act + validatorProvider.GetValidators(context); + + // Assert + var validators = context.Validators; + + Assert.IsType(Assert.Single(validators)); + } + + [Fact] + public void GetValidators_FromModelMetadataType_MergedValidators() + { + // Arrange + var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); + var validatorProvider = TestModelValidatorProvider.CreateDefaultProvider(); + + var metadata = metadataProvider.GetMetadataForProperty( + typeof(ProductViewModel), + nameof(ProductViewModel.Name)); + var context = new ModelValidatorProviderContext(metadata); + + // Act + validatorProvider.GetValidators(context); + + // Assert + var validators = context.Validators; + + Assert.Equal(2, validators.Count); + Assert.Single(validators, v => v is RegularExpressionAttributeAdapter); + Assert.Single(validators, v => v is StringLengthAttributeAdapter); + } + + private class ValidatableObject : IValidatableObject + { + public IEnumerable Validate(ValidationContext validationContext) + { + return null; + } + } + + [CustomModelValidator(Tag = "Class")] + private class ModelValidatorAttributeOnClass + { + } + + + private class ModelValidatorAttributeOnProperty + { + [CustomModelValidator(Tag = "Property")] + public string Property { get; set; } + } + + private class ModelValidatorAttributeOnPropertyAndClass + { + [CustomModelValidator(Tag = "Property")] + public ModelValidatorAttributeOnClass Property { get; set; } + } + + private class CustomModelValidatorAttribute : Attribute, IModelValidator + { + public string Tag { get; set; } + + public bool IsRequired + { + get + { + throw new NotImplementedException(); + } + } + + public IEnumerable Validate(ModelValidationContext context) + { + throw new NotImplementedException(); + } + } + + private class RangeAttributeOnProperty + { + [Range(0, 10)] + public int Property { get; set; } + } + + private class CustomValidationAttribute : ValidationAttribute + { + } + + private class CustomValidationAttributeOnProperty + { + [CustomValidation] + public int Property { get; set; } + } + + private class ProductEntity + { + [Range(0, 10)] + public int Id { get; set; } + + [RegularExpression(".*")] + public string Name { get; set; } + } + + [ModelMetadataType(typeof(ProductEntity))] + private class ProductViewModel + { + public int Id { get; set; } + + [StringLength(4)] + public string Name { get; set; } + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DefaultObjectValidatorTests.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DefaultObjectValidatorTests.cs index 3715fe3337..9b983d589a 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DefaultObjectValidatorTests.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/DefaultObjectValidatorTests.cs @@ -5,16 +5,12 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using System.Globalization; -using System.IO; using System.Linq; -using System.Xml; -using System.Xml.Linq; using Microsoft.AspNet.Testing; using Moq; using Xunit; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class DefaultObjectValidatorTests { @@ -489,12 +485,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding { var modelStateDictionary = new ModelStateDictionary(); - var providers = new IModelValidatorProvider[] - { - new DataAnnotationsModelValidatorProvider(), - new DataMemberModelValidatorProvider() - }; - var modelMetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(); var excludedValidationTypesPredicate = new List(); @@ -519,7 +509,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding { ModelValidationContext = new ModelValidationContext( key, - new CompositeModelValidatorProvider(providers), + TestModelValidatorProvider.CreateDefaultProvider(), modelStateDictionary, modelExplorer), ModelMetadataProvider = modelMetadataProvider, diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/MaxLengthAttributeAdapterTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/MaxLengthAttributeAdapterTest.cs index 55e6bd8bf1..6a39915f1f 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/MaxLengthAttributeAdapterTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/MaxLengthAttributeAdapterTest.cs @@ -6,7 +6,7 @@ using Microsoft.AspNet.Testing; using Microsoft.Framework.DependencyInjection; using Xunit; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class MaxLengthAttributeAdapterTest { diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/MinLengthAttributeAdapterTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/MinLengthAttributeAdapterTest.cs index b655485bad..847b4d7668 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/MinLengthAttributeAdapterTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/MinLengthAttributeAdapterTest.cs @@ -6,7 +6,7 @@ using Microsoft.AspNet.Testing; using Microsoft.Framework.DependencyInjection; using Xunit; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class MinLengthAttributeAdapterTest { diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/RangeAttributeAdapterTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/RangeAttributeAdapterTest.cs index 0dcf505634..58a87bec3e 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/RangeAttributeAdapterTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/RangeAttributeAdapterTest.cs @@ -6,7 +6,7 @@ using Microsoft.AspNet.Testing; using Microsoft.Framework.DependencyInjection; using Xunit; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class RangeAttributeAdapterTest { diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/ReferenceEqualityComparerTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/ReferenceEqualityComparerTest.cs index bdd5398ca5..82a55d73e8 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/ReferenceEqualityComparerTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/ReferenceEqualityComparerTest.cs @@ -4,7 +4,7 @@ using System; using Xunit; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class ReferenceEqualityComparerTest { diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/RequiredAttributeAdapterTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/RequiredAttributeAdapterTest.cs index 03dbbe0146..d5391ade8b 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/RequiredAttributeAdapterTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/RequiredAttributeAdapterTest.cs @@ -6,7 +6,7 @@ using Microsoft.AspNet.Testing; using Microsoft.Framework.DependencyInjection; using Xunit; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class RequiredAttributeAdapterTest { diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/StringLengthAttributeAdapterTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/StringLengthAttributeAdapterTest.cs index 36243d40f6..9bc1f11e86 100644 --- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/StringLengthAttributeAdapterTest.cs +++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Validation/StringLengthAttributeAdapterTest.cs @@ -6,7 +6,7 @@ using Microsoft.AspNet.Testing; using Microsoft.Framework.DependencyInjection; using Xunit; -namespace Microsoft.AspNet.Mvc.ModelBinding +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation { public class StringLengthAttributeAdapterTest { diff --git a/test/Microsoft.AspNet.Mvc.Test/MvcOptionsSetupTest.cs b/test/Microsoft.AspNet.Mvc.Test/MvcOptionsSetupTest.cs index 3f16a5ad2d..6328a70e30 100644 --- a/test/Microsoft.AspNet.Mvc.Test/MvcOptionsSetupTest.cs +++ b/test/Microsoft.AspNet.Mvc.Test/MvcOptionsSetupTest.cs @@ -4,6 +4,7 @@ using System; using System.Xml.Linq; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Mvc.Razor; using Newtonsoft.Json.Linq; using Xunit; @@ -118,8 +119,8 @@ namespace Microsoft.AspNet.Mvc // Assert Assert.Equal(2, mvcOptions.ModelValidatorProviders.Count); - Assert.IsType(mvcOptions.ModelValidatorProviders[0].Instance); - Assert.IsType(mvcOptions.ModelValidatorProviders[1].Instance); + Assert.IsType(mvcOptions.ModelValidatorProviders[0].Instance); + Assert.IsType(mvcOptions.ModelValidatorProviders[1].Instance); } [Fact] diff --git a/test/Microsoft.AspNet.Mvc.TestCommon/TestModelMetadataProvider.cs b/test/Microsoft.AspNet.Mvc.TestCommon/TestModelMetadataProvider.cs index 6b18cb7a70..ab27911a72 100644 --- a/test/Microsoft.AspNet.Mvc.TestCommon/TestModelMetadataProvider.cs +++ b/test/Microsoft.AspNet.Mvc.TestCommon/TestModelMetadataProvider.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Reflection; using Microsoft.AspNet.Mvc.ModelBinding.Metadata; -using Microsoft.Framework.Internal; using Xunit; namespace Microsoft.AspNet.Mvc.ModelBinding @@ -18,7 +17,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var detailsProviders = new IMetadataDetailsProvider[] { new DefaultBindingMetadataProvider(), - new DataAnnotationsMetadataDetailsProvider(), + new DefaultValidationMetadataProvider(), + new DataAnnotationsMetadataProvider(), + new DataMemberRequiredValidationMetadataProvider(), }; var compositeDetailsProvider = new DefaultCompositeMetadataDetailsProvider(detailsProviders); @@ -36,7 +37,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding : base(new DefaultCompositeMetadataDetailsProvider(new IMetadataDetailsProvider[] { new DefaultBindingMetadataProvider(), - new DataAnnotationsMetadataDetailsProvider(), + new DefaultValidationMetadataProvider(), + new DataAnnotationsMetadataProvider(), detailsProvider })) { diff --git a/test/Microsoft.AspNet.Mvc.TestCommon/TestModelValidatorProvider.cs b/test/Microsoft.AspNet.Mvc.TestCommon/TestModelValidatorProvider.cs new file mode 100644 index 0000000000..3a141d908f --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.TestCommon/TestModelValidatorProvider.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; + +namespace Microsoft.AspNet.Mvc.ModelBinding.Validation +{ + internal class TestModelValidatorProvider : CompositeModelValidatorProvider + { + // Creates a provider with all the defaults - includes data annotations + public static IModelValidatorProvider CreateDefaultProvider() + { + var providers = new IModelValidatorProvider[] + { + new DefaultModelValidatorProvider(), + new DataAnnotationsModelValidatorProvider(), + }; + + return new TestModelValidatorProvider(providers); + } + + public TestModelValidatorProvider(IEnumerable providers) + : base(providers) + { + } + } +} \ No newline at end of file diff --git a/test/WebSites/ModelBindingWebSite/Controllers/VehicleController.cs b/test/WebSites/ModelBindingWebSite/Controllers/VehicleController.cs index c130d226fa..956c906c0b 100644 --- a/test/WebSites/ModelBindingWebSite/Controllers/VehicleController.cs +++ b/test/WebSites/ModelBindingWebSite/Controllers/VehicleController.cs @@ -37,7 +37,7 @@ namespace ModelBindingWebSite [HttpPut("/api/vehicles/{id}")] [Produces("application/json")] public object UpdateVehicleApi( - [Range(1, 500)] int id, + int id, [FromBody] VehicleViewModel model, [FromServices] IVehicleService service, [FromHeader(Name = "X-TrackingId")] string trackingId)