Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
Moving IModelValidatorProvider to Options
Browse files Browse the repository at this point in the history
Fixes #879
  • Loading branch information
pranavkm committed Aug 22, 2014
1 parent 2dcbbf7 commit b72d3ff
Show file tree
Hide file tree
Showing 34 changed files with 605 additions and 128 deletions.
2 changes: 1 addition & 1 deletion src/Microsoft.AspNet.Mvc.Core/Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ public virtual async Task<bool> TryUpdateModelAsync<TModel>([NotNull] TModel mod
bindingContext.MetadataProvider,
bindingContext.ModelBinder,
valueProvider,
bindingContext.ValidatorProviders);
bindingContext.ValidatorProvider);
}
}
}
2 changes: 1 addition & 1 deletion src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ internal async Task<IDictionary<string, object>> GetActionArguments(ModelStateDi
ModelMetadata = modelMetadata,
ModelBinder = actionBindingContext.ModelBinder,
ValueProvider = actionBindingContext.ValueProvider,
ValidatorProviders = actionBindingContext.ValidatorProviders,
ValidatorProvider = actionBindingContext.ValidatorProvider,
MetadataProvider = metadataProvider,
HttpContext = actionBindingContext.ActionContext.HttpContext,
FallbackToEmptyPrefix = true
Expand Down
6 changes: 6 additions & 0 deletions src/Microsoft.AspNet.Mvc.Core/MvcOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ public RazorViewEngineOptions ViewEngineOptions
/// </summary>
public List<ModelBinderDescriptor> ModelBinders { get; private set; }

/// <summary>
/// Get a list of the <see cref="IModelValidatorProvider" /> used by this application.
/// </summary>
public List<ModelValidatorProviderDescriptor> ModelValidatorProviders { get; } =
new List<ModelValidatorProviderDescriptor>();

/// <summary>
/// Gets a list of descriptors that represent <see cref="Rendering.IViewEngine"/> used
/// by this application.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// 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 Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.OptionsModel;

namespace Microsoft.AspNet.Mvc.OptionDescriptors
{
/// <inheritdoc />
public class DefaultModelValidatorProviderProvider : OptionDescriptorBasedProvider<IModelValidatorProvider>,
IModelValidatorProviderProvider
{
/// <summary>
/// Initializes a new instance of the <see cref="DefaultModelValidatorProviderProvider"/> class.
/// </summary>
/// <param name="options">An accessor to the <see cref="MvcOptions"/> configured for this application.</param>
/// <param name="typeActivator">An <see cref="ITypeActivator"/> instance used to instantiate types.</param>
/// <param name="serviceProvider">A <see cref="IServiceProvider"/> instance that retrieves services from the
/// service collection.</param>
public DefaultModelValidatorProviderProvider(
IOptionsAccessor<MvcOptions> optionsAccessor,
ITypeActivator typeActivator,
IServiceProvider serviceProvider)
: base(optionsAccessor.Options.ModelValidatorProviders, typeActivator, serviceProvider)
{
}

/// <inheritdoc />
public IReadOnlyList<IModelValidatorProvider> ModelValidatorProviders
{
get { return Options; }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// 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;

namespace Microsoft.AspNet.Mvc.OptionDescriptors
{
/// <summary>
/// Encapsulates information that describes an <see cref="IModelValidatorProvider"/>.
/// </summary>
public class ModelValidatorProviderDescriptor : OptionDescriptor<IModelValidatorProvider>
{
/// <summary>
/// Creates a new instance of <see cref="ModelValidatorProviderDescriptor"/>.
/// </summary>
/// <param name="type">A type that represents a <see cref="IModelValidatorProvider"/>.</param>
public ModelValidatorProviderDescriptor([NotNull] Type type)
: base(type)
{
}

/// <summary>
/// Creates a new instance of <see cref="ModelValidatorProviderDescriptor"/> with the specified instance.
/// </summary>
/// <param name="option">An instance of <see cref="IModelValidatorProvider"/>.</param>
public ModelValidatorProviderDescriptor([NotNull] IModelValidatorProvider validatorProvider)
: base(validatorProvider)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// 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 Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.OptionDescriptors;

namespace Microsoft.AspNet.Mvc
{
/// <summary>
/// Extension methods for adding validator provider to a collection.
/// </summary>
public static class ModelValidatorProviderDescriptorExtensions
{
/// <summary>
/// Adds a type representing a <see cref="IModelValidatorProvider"/> to <paramref name="descriptors"/>.
/// </summary>
/// <param name="descriptors">A list of <see cref="ModelValidatorProviderDescriptor"/>.</param>
/// <param name="modelValidatorProviderType">Type representing an <see cref="IModelValidatorProvider"/></param>
/// <returns>A <see cref="ModelValidatorProviderDescriptor"/> representing the added instance.</returns>
public static ModelValidatorProviderDescriptor Add(
[NotNull] this IList<ModelValidatorProviderDescriptor> descriptors,
[NotNull] Type modelValidatorProviderType)
{
var descriptor = new ModelValidatorProviderDescriptor(modelValidatorProviderType);
descriptors.Add(descriptor);
return descriptor;
}

/// <summary>
/// Inserts a type representing a <see cref="IModelValidatorProvider"/> in to <paramref name="descriptors"/> at
/// the specified <paramref name="index"/>.
/// </summary>
/// <param name="descriptors">A list of <see cref="ModelValidatorProviderDescriptor"/>.</param>
/// <param name="index">The zero-based index at which <paramref name="modelValidatorProviderType"/>
/// should be inserted.</param>
/// <param name="modelValidatorProviderType">Type representing an <see cref="IModelValidatorProvider"/></param>
/// <returns>A <see cref="ModelValidatorProviderDescriptor"/> representing the inserted instance.</returns>
public static ModelValidatorProviderDescriptor Insert(
[NotNull] this IList<ModelValidatorProviderDescriptor> descriptors,
int index,
[NotNull] Type modelValidatorProviderType)
{
if (index < 0 || index > descriptors.Count)
{
throw new ArgumentOutOfRangeException(nameof(index));
}

var descriptor = new ModelValidatorProviderDescriptor(modelValidatorProviderType);
descriptors.Insert(index, descriptor);
return descriptor;
}

/// <summary>
/// Adds an <see cref="IModelValidatorProvider"/> to <paramref name="descriptors"/>.
/// </summary>
/// <param name="descriptors">A list of <see cref="ModelValidatorProviderDescriptor"/>.</param>
/// <param name="modelValidatorProvider">An <see cref="IModelBinder"/> instance.</param>
/// <returns>A <see cref="ModelValidatorProviderDescriptor"/> representing the added instance.</returns>
public static ModelValidatorProviderDescriptor Add(
[NotNull] this IList<ModelValidatorProviderDescriptor> descriptors,
[NotNull] IModelValidatorProvider modelValidatorProvider)
{
var descriptor = new ModelValidatorProviderDescriptor(modelValidatorProvider);
descriptors.Add(descriptor);
return descriptor;
}

/// <summary>
/// Insert an <see cref="IModelValidatorProvider"/> in to <paramref name="descriptors"/> at the specified
/// <paramref name="index"/>.
/// </summary>
/// <param name="descriptors">A list of <see cref="ModelValidatorProviderDescriptor"/>.</param>
/// <param name="index">The zero-based index at which <paramref name="modelValidatorProvider"/>
/// should be inserted.</param>
/// <param name="modelValidatorProvider">An <see cref="IModelBinder"/> instance.</param>
/// <returns>A <see cref="ModelValidatorProviderDescriptor"/> representing the added instance.</returns>
public static ModelValidatorProviderDescriptor Insert(
[NotNull] this IList<ModelValidatorProviderDescriptor> descriptors,
int index,
[NotNull] IModelValidatorProvider modelValidatorProvider)
{
if (index < 0 || index > descriptors.Count)
{
throw new ArgumentOutOfRangeException(nameof(index));
}

var descriptor = new ModelValidatorProviderDescriptor(modelValidatorProvider);
descriptors.Insert(index, descriptor);
return descriptor;
}
}
}
Original file line number Diff line number Diff line change
@@ -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 Microsoft.AspNet.Mvc.ModelBinding;

namespace Microsoft.AspNet.Mvc
Expand All @@ -13,14 +12,14 @@ public ActionBindingContext(ActionContext context,
IModelBinder modelBinder,
IValueProvider valueProvider,
IInputFormatterSelector inputFormatterSelector,
IEnumerable<IModelValidatorProvider> validatorProviders)
IModelValidatorProvider validatorProvider)
{
ActionContext = context;
MetadataProvider = metadataProvider;
ModelBinder = modelBinder;
ValueProvider = valueProvider;
InputFormatterSelector = inputFormatterSelector;
ValidatorProviders = validatorProviders;
ValidatorProvider = validatorProvider;
}

public ActionContext ActionContext { get; private set; }
Expand All @@ -33,6 +32,6 @@ public ActionBindingContext(ActionContext context,

public IInputFormatterSelector InputFormatterSelector { get; private set; }

public IEnumerable<IModelValidatorProvider> ValidatorProviders { get; private set; }
public IModelValidatorProvider ValidatorProvider { get; private set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding;

Expand All @@ -14,20 +13,20 @@ public class DefaultActionBindingContextProvider : IActionBindingContextProvider
private readonly ICompositeModelBinder _compositeModelBinder;
private readonly IValueProviderFactory _compositeValueProviderFactory;
private readonly IInputFormatterSelector _inputFormatterSelector;
private readonly IEnumerable<IModelValidatorProvider> _validatorProviders;
private readonly ICompositeModelValidatorProvider _validatorProvider;
private Tuple<ActionContext, ActionBindingContext> _bindingContext;

public DefaultActionBindingContextProvider(IModelMetadataProvider modelMetadataProvider,
ICompositeModelBinder compositeModelBinder,
ICompositeValueProviderFactory compositeValueProviderFactory,
IInputFormatterSelector inputFormatterProvider,
IEnumerable<IModelValidatorProvider> validatorProviders)
ICompositeModelValidatorProvider validatorProvider)
{
_modelMetadataProvider = modelMetadataProvider;
_compositeModelBinder = compositeModelBinder;
_compositeValueProviderFactory = compositeValueProviderFactory;
_inputFormatterSelector = inputFormatterProvider;
_validatorProviders = validatorProviders;
_validatorProvider = validatorProvider;
}

public Task<ActionBindingContext> GetActionBindingContextAsync(ActionContext actionContext)
Expand All @@ -52,7 +51,7 @@ public Task<ActionBindingContext> GetActionBindingContextAsync(ActionContext act
_compositeModelBinder,
valueProvider,
_inputFormatterSelector,
_validatorProviders);
_validatorProvider);

_bindingContext = new Tuple<ActionContext, ActionBindingContext>(actionContext, context);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public static class ModelBindingHelper
/// <param name="metadataProvider">The provider used for reading metadata for the model type.</param>
/// <param name="modelBinder">The model binder used for binding.</param>
/// <param name="valueProvider">The value provider used for looking up values.</param>
/// <param name="validatorProviders">The validator providers used for executing validation
/// on the model instance.</param>
/// <param name="validatorProvider">The validator provider used for executing validation on the model
/// instance.</param>
/// <returns>A Task with a value representing if the the update is successful.</returns>
public static async Task<bool> TryUpdateModelAsync<TModel>(
[NotNull] TModel model,
Expand All @@ -34,7 +34,7 @@ public static async Task<bool> TryUpdateModelAsync<TModel>(
[NotNull] IModelMetadataProvider metadataProvider,
[NotNull] IModelBinder modelBinder,
[NotNull] IValueProvider valueProvider,
[NotNull] IEnumerable<IModelValidatorProvider> validatorProviders)
[NotNull] IModelValidatorProvider validatorProvider)
where TModel : class
{
var modelMetadata = metadataProvider.GetMetadataForType(
Expand All @@ -49,7 +49,7 @@ public static async Task<bool> TryUpdateModelAsync<TModel>(
ModelState = modelState,
ModelBinder = modelBinder,
ValueProvider = valueProvider,
ValidatorProviders = validatorProviders,
ValidatorProvider = validatorProvider,
MetadataProvider = metadataProvider,
FallbackToEmptyPrefix = true,
HttpContext = httpContext
Expand Down
13 changes: 6 additions & 7 deletions src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1315,13 +1315,12 @@ public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
string name)
{
var actionBindingContext = _actionBindingContextProvider.GetActionBindingContextAsync(ViewContext).Result;
metadata = metadata ??
ExpressionMetadataProvider.FromStringExpression(name, ViewData, MetadataProvider);
return actionBindingContext.ValidatorProviders
.SelectMany(vp => vp.GetValidators(metadata))
.OfType<IClientModelValidator>()
.SelectMany(v => v.GetClientValidationRules(
new ClientModelValidationContext(metadata, MetadataProvider)));
metadata = metadata ?? ExpressionMetadataProvider.FromStringExpression(name, ViewData, MetadataProvider);
return actionBindingContext.ValidatorProvider
.GetValidators(metadata)
.OfType<IClientModelValidator>()
.SelectMany(v => v.GetClientValidationRules(
new ClientModelValidationContext(metadata, MetadataProvider)));
}

// Only need a dictionary if htmlAttributes is non-null. TagBuilder.MergeAttributes() is fine with null.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public virtual async Task<bool> BindModelAsync([NotNull] ModelBindingContext bin
}

var validationContext = new ModelValidationContext(bindingContext.MetadataProvider,
bindingContext.ValidatorProviders,
bindingContext.ValidatorProvider,
bindingContext.ModelState,
bindingContext.ModelMetadata,
containerMetadata: null);
Expand Down Expand Up @@ -120,7 +120,7 @@ private static ModelBindingContext CreateNewBindingContext(ModelBindingContext o
ModelName = modelName,
ModelState = oldBindingContext.ModelState,
ValueProvider = oldBindingContext.ValueProvider,
ValidatorProviders = oldBindingContext.ValidatorProviders,
ValidatorProvider = oldBindingContext.ValidatorProvider,
MetadataProvider = oldBindingContext.MetadataProvider,
ModelBinder = oldBindingContext.ModelBinder,
HttpContext = oldBindingContext.HttpContext
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,9 @@ internal static PropertyValidationInfo GetPropertyValidationInfo(ModelBindingCon
{
var propertyName = property.Name;
var propertyMetadata = bindingContext.PropertyMetadata[propertyName];
var requiredValidator = bindingContext.GetValidators(propertyMetadata)
.FirstOrDefault(v => v.IsRequired);
var requiredValidator = bindingContext.ValidatorProvider
.GetValidators(propertyMetadata)
.FirstOrDefault(v => v != null && v.IsRequired);
if (requiredValidator != null)
{
validationInfo.RequiredValidators[propertyName] = requiredValidator;
Expand Down
Loading

0 comments on commit b72d3ff

Please sign in to comment.