Move ModelExplorer to ViewFeatures
This commit is contained in:
parent
ec18b35123
commit
0d6edf240a
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.AspNet.Mvc.Core;
|
using Microsoft.AspNet.Mvc.Core;
|
||||||
using Microsoft.Framework.Internal;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
|
|
@ -12,25 +11,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class ModelMetadataProviderExtensions
|
public static class ModelMetadataProviderExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets a <see cref="ModelExplorer"/> for the provided <paramref name="modelType"/> and
|
|
||||||
/// <paramref name="model"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="provider">The <see cref="IModelMetadataProvider"/>.</param>
|
|
||||||
/// <param name="modelType">The declared <see cref="Type"/> of the model object.</param>
|
|
||||||
/// <param name="model">The model object.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// A <see cref="ModelExplorer"/> for the <paramref name="modelType"/> and <paramref name="model"/>.
|
|
||||||
/// </returns>
|
|
||||||
public static ModelExplorer GetModelExplorerForType(
|
|
||||||
[NotNull] this IModelMetadataProvider provider,
|
|
||||||
[NotNull] Type modelType,
|
|
||||||
object model)
|
|
||||||
{
|
|
||||||
var modelMetadata = provider.GetMetadataForType(modelType);
|
|
||||||
return new ModelExplorer(provider, modelMetadata, model);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a <see cref="ModelMetadata"/> for property identified by the provided
|
/// Gets a <see cref="ModelMetadata"/> for property identified by the provided
|
||||||
/// <paramref name="containerType"/> and <paramref name="propertyName"/>.
|
/// <paramref name="containerType"/> and <paramref name="propertyName"/>.
|
||||||
|
|
@ -40,10 +20,25 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// <param name="propertyName">The property name.</param>
|
/// <param name="propertyName">The property name.</param>
|
||||||
/// <returns>A <see cref="ModelMetadata"/> for the property.</returns>
|
/// <returns>A <see cref="ModelMetadata"/> for the property.</returns>
|
||||||
public static ModelMetadata GetMetadataForProperty(
|
public static ModelMetadata GetMetadataForProperty(
|
||||||
[NotNull] this IModelMetadataProvider provider,
|
this IModelMetadataProvider provider,
|
||||||
[NotNull] Type containerType,
|
Type containerType,
|
||||||
[NotNull] string propertyName)
|
string propertyName)
|
||||||
{
|
{
|
||||||
|
if (provider == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(provider));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containerType == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(containerType));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propertyName == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(propertyName));
|
||||||
|
}
|
||||||
|
|
||||||
var containerMetadata = provider.GetMetadataForType(containerType);
|
var containerMetadata = provider.GetMetadataForType(containerType);
|
||||||
|
|
||||||
var propertyMetadata = containerMetadata.Properties[propertyName];
|
var propertyMetadata = containerMetadata.Properties[propertyName];
|
||||||
|
|
|
||||||
|
|
@ -398,8 +398,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
IDictionary<ModelMetadata, ModelBindingResult> results)
|
IDictionary<ModelMetadata, ModelBindingResult> results)
|
||||||
{
|
{
|
||||||
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
||||||
var modelExplorer =
|
var metadata = metadataProvider.GetMetadataForType(bindingContext.ModelType);
|
||||||
metadataProvider.GetModelExplorerForType(bindingContext.ModelType, bindingContext.Model);
|
|
||||||
var validationInfo = GetPropertyValidationInfo(bindingContext);
|
var validationInfo = GetPropertyValidationInfo(bindingContext);
|
||||||
|
|
||||||
// Eliminate provided properties from RequiredProperties; leaving just *missing* required properties.
|
// Eliminate provided properties from RequiredProperties; leaving just *missing* required properties.
|
||||||
|
|
@ -408,8 +408,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
|
||||||
foreach (var missingRequiredProperty in validationInfo.RequiredProperties)
|
foreach (var missingRequiredProperty in validationInfo.RequiredProperties)
|
||||||
{
|
{
|
||||||
var propertyExplorer = modelExplorer.GetExplorerForProperty(missingRequiredProperty);
|
var propertyMetadata = metadata.Properties[missingRequiredProperty];
|
||||||
var propertyName = propertyExplorer.Metadata.BinderModelName ?? missingRequiredProperty;
|
var propertyName = propertyMetadata.BinderModelName ?? missingRequiredProperty;
|
||||||
var modelStateKey = ModelNames.CreatePropertyModelName(bindingContext.ModelName, propertyName);
|
var modelStateKey = ModelNames.CreatePropertyModelName(bindingContext.ModelName, propertyName);
|
||||||
|
|
||||||
bindingContext.ModelState.TryAddModelError(
|
bindingContext.ModelState.TryAddModelError(
|
||||||
|
|
@ -425,7 +425,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
var result = entry.Value;
|
var result = entry.Value;
|
||||||
var propertyMetadata = entry.Key;
|
var propertyMetadata = entry.Key;
|
||||||
SetProperty(bindingContext, modelExplorer, propertyMetadata, result);
|
SetProperty(bindingContext, metadata, propertyMetadata, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -434,15 +434,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// Updates a property in the current <see cref="ModelBindingContext.Model"/>.
|
/// Updates a property in the current <see cref="ModelBindingContext.Model"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="bindingContext">The <see cref="ModelBindingContext"/>.</param>
|
/// <param name="bindingContext">The <see cref="ModelBindingContext"/>.</param>
|
||||||
/// <param name="modelExplorer">
|
/// <param name="metadata">
|
||||||
/// The <see cref="ModelExplorer"/> for the model containing property to set.
|
/// The <see cref="ModelMetadata"/> for the model containing property to set.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="propertyMetadata">The <see cref="ModelMetadata"/> for the property to set.</param>
|
/// <param name="propertyMetadata">The <see cref="ModelMetadata"/> for the property to set.</param>
|
||||||
/// <param name="result">The <see cref="ModelBindingResult"/> for the property's new value.</param>
|
/// <param name="result">The <see cref="ModelBindingResult"/> for the property's new value.</param>
|
||||||
/// <remarks>Should succeed in all cases that <see cref="CanUpdateProperty"/> returns <c>true</c>.</remarks>
|
/// <remarks>Should succeed in all cases that <see cref="CanUpdateProperty"/> returns <c>true</c>.</remarks>
|
||||||
protected virtual void SetProperty(
|
protected virtual void SetProperty(
|
||||||
[NotNull] ModelBindingContext bindingContext,
|
[NotNull] ModelBindingContext bindingContext,
|
||||||
[NotNull] ModelExplorer modelExplorer,
|
[NotNull] ModelMetadata metadata,
|
||||||
[NotNull] ModelMetadata propertyMetadata,
|
[NotNull] ModelMetadata propertyMetadata,
|
||||||
[NotNull] ModelBindingResult result)
|
[NotNull] ModelBindingResult result)
|
||||||
{
|
{
|
||||||
|
|
@ -464,7 +464,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
if (!property.CanWrite)
|
if (!property.CanWrite)
|
||||||
{
|
{
|
||||||
// Try to handle as a collection if property exists but is not settable.
|
// Try to handle as a collection if property exists but is not settable.
|
||||||
AddToProperty(bindingContext, modelExplorer, property, result);
|
AddToProperty(bindingContext, metadata, property, result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -481,13 +481,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
|
||||||
private void AddToProperty(
|
private void AddToProperty(
|
||||||
ModelBindingContext bindingContext,
|
ModelBindingContext bindingContext,
|
||||||
ModelExplorer modelExplorer,
|
ModelMetadata modelMetadata,
|
||||||
PropertyInfo property,
|
PropertyInfo property,
|
||||||
ModelBindingResult result)
|
ModelBindingResult result)
|
||||||
{
|
{
|
||||||
var propertyExplorer = modelExplorer.GetExplorerForProperty(property.Name);
|
var propertyMetadata = modelMetadata.Properties[property.Name];
|
||||||
|
|
||||||
var target = propertyExplorer.Model;
|
var target = propertyMetadata.PropertyGetter(bindingContext.Model);
|
||||||
var source = result.Model;
|
var source = result.Model;
|
||||||
if (target == null || source == null)
|
if (target == null || source == null)
|
||||||
{
|
{
|
||||||
|
|
@ -504,14 +504,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
// Determine T if this is an ICollection<T> property. No need for a T[] case because CanUpdateProperty()
|
// Determine T if this is an ICollection<T> property. No need for a T[] case because CanUpdateProperty()
|
||||||
// ensures property is either settable or not an array. Underlying assumption is that CanUpdateProperty()
|
// ensures property is either settable or not an array. Underlying assumption is that CanUpdateProperty()
|
||||||
// and SetProperty() are overridden together.
|
// and SetProperty() are overridden together.
|
||||||
if (!propertyExplorer.Metadata.IsCollectionType)
|
if (!propertyMetadata.IsCollectionType)
|
||||||
{
|
{
|
||||||
// Not a collection model.
|
// Not a collection model.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var propertyAddRange = CallPropertyAddRangeOpenGenericMethod.MakeGenericMethod(
|
var propertyAddRange = CallPropertyAddRangeOpenGenericMethod.MakeGenericMethod(
|
||||||
propertyExplorer.Metadata.ElementMetadata.ModelType);
|
propertyMetadata.ElementMetadata.ModelType);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
propertyAddRange.Invoke(obj: null, parameters: new[] { target, source });
|
propertyAddRange.Invoke(obj: null, parameters: new[] { target, source });
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,10 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.Framework.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ViewFeatures
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Associates a model object with it's corresponding <see cref="ModelMetadata"/>.
|
/// Associates a model object with it's corresponding <see cref="ModelMetadata"/>.
|
||||||
|
|
@ -29,10 +30,20 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// <param name="metadata">The <see cref="ModelMetadata"/>.</param>
|
/// <param name="metadata">The <see cref="ModelMetadata"/>.</param>
|
||||||
/// <param name="model">The model object. May be <c>null</c>.</param>
|
/// <param name="model">The model object. May be <c>null</c>.</param>
|
||||||
public ModelExplorer(
|
public ModelExplorer(
|
||||||
[NotNull] IModelMetadataProvider metadataProvider,
|
IModelMetadataProvider metadataProvider,
|
||||||
[NotNull] ModelMetadata metadata,
|
ModelMetadata metadata,
|
||||||
object model)
|
object model)
|
||||||
{
|
{
|
||||||
|
if (metadataProvider == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(metadataProvider));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metadata == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(metadata));
|
||||||
|
}
|
||||||
|
|
||||||
_metadataProvider = metadataProvider;
|
_metadataProvider = metadataProvider;
|
||||||
Metadata = metadata;
|
Metadata = metadata;
|
||||||
_model = model;
|
_model = model;
|
||||||
|
|
@ -46,11 +57,26 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// <param name="metadata">The <see cref="ModelMetadata"/>.</param>
|
/// <param name="metadata">The <see cref="ModelMetadata"/>.</param>
|
||||||
/// <param name="modelAccessor">A model accessor function. May be <c>null</c>.</param>
|
/// <param name="modelAccessor">A model accessor function. May be <c>null</c>.</param>
|
||||||
public ModelExplorer(
|
public ModelExplorer(
|
||||||
[NotNull] IModelMetadataProvider metadataProvider,
|
IModelMetadataProvider metadataProvider,
|
||||||
[NotNull] ModelExplorer container,
|
ModelExplorer container,
|
||||||
[NotNull] ModelMetadata metadata,
|
ModelMetadata metadata,
|
||||||
Func<object, object> modelAccessor)
|
Func<object, object> modelAccessor)
|
||||||
{
|
{
|
||||||
|
if (metadataProvider == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(metadataProvider));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (container == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(container));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metadata == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(metadata));
|
||||||
|
}
|
||||||
|
|
||||||
_metadataProvider = metadataProvider;
|
_metadataProvider = metadataProvider;
|
||||||
Container = container;
|
Container = container;
|
||||||
Metadata = metadata;
|
Metadata = metadata;
|
||||||
|
|
@ -65,11 +91,21 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// <param name="metadata">The <see cref="ModelMetadata"/>.</param>
|
/// <param name="metadata">The <see cref="ModelMetadata"/>.</param>
|
||||||
/// <param name="model">The model object. May be <c>null</c>.</param>
|
/// <param name="model">The model object. May be <c>null</c>.</param>
|
||||||
public ModelExplorer(
|
public ModelExplorer(
|
||||||
[NotNull] IModelMetadataProvider metadataProvider,
|
IModelMetadataProvider metadataProvider,
|
||||||
[NotNull] ModelExplorer container,
|
ModelExplorer container,
|
||||||
[NotNull] ModelMetadata metadata,
|
ModelMetadata metadata,
|
||||||
object model)
|
object model)
|
||||||
{
|
{
|
||||||
|
if (metadataProvider == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(metadataProvider));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metadata == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(metadata));
|
||||||
|
}
|
||||||
|
|
||||||
_metadataProvider = metadataProvider;
|
_metadataProvider = metadataProvider;
|
||||||
Container = container;
|
Container = container;
|
||||||
Metadata = metadata;
|
Metadata = metadata;
|
||||||
|
|
@ -216,8 +252,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The property name.</param>
|
/// <param name="name">The property name.</param>
|
||||||
/// <returns>A <see cref="ModelExplorer"/>, or <c>null</c>.</returns>
|
/// <returns>A <see cref="ModelExplorer"/>, or <c>null</c>.</returns>
|
||||||
public ModelExplorer GetExplorerForProperty([NotNull] string name)
|
public ModelExplorer GetExplorerForProperty(string name)
|
||||||
{
|
{
|
||||||
|
if (name == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(name));
|
||||||
|
}
|
||||||
|
|
||||||
return Properties.FirstOrDefault(p => string.Equals(
|
return Properties.FirstOrDefault(p => string.Equals(
|
||||||
p.Metadata.PropertyName,
|
p.Metadata.PropertyName,
|
||||||
name,
|
name,
|
||||||
|
|
@ -234,8 +275,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// As this creates a model explorer with a specific model accessor function, the result is not cached.
|
/// As this creates a model explorer with a specific model accessor function, the result is not cached.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public ModelExplorer GetExplorerForProperty([NotNull] string name, Func<object, object> modelAccessor)
|
public ModelExplorer GetExplorerForProperty(string name, Func<object, object> modelAccessor)
|
||||||
{
|
{
|
||||||
|
if (name == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(name));
|
||||||
|
}
|
||||||
|
|
||||||
var metadata = GetMetadataForRuntimeType();
|
var metadata = GetMetadataForRuntimeType();
|
||||||
|
|
||||||
var propertyMetadata = metadata.Properties[name];
|
var propertyMetadata = metadata.Properties[name];
|
||||||
|
|
@ -257,8 +303,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// As this creates a model explorer with a specific model value, the result is not cached.
|
/// As this creates a model explorer with a specific model value, the result is not cached.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public ModelExplorer GetExplorerForProperty([NotNull] string name, object model)
|
public ModelExplorer GetExplorerForProperty(string name, object model)
|
||||||
{
|
{
|
||||||
|
if (name == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(name));
|
||||||
|
}
|
||||||
|
|
||||||
var metadata = GetMetadataForRuntimeType();
|
var metadata = GetMetadataForRuntimeType();
|
||||||
|
|
||||||
var propertyMetadata = metadata.Properties[name];
|
var propertyMetadata = metadata.Properties[name];
|
||||||
|
|
@ -286,8 +337,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// The returned <see cref="ModelExplorer"/> will have the current instance set as its <see cref="Container"/>.
|
/// The returned <see cref="ModelExplorer"/> will have the current instance set as its <see cref="Container"/>.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public ModelExplorer GetExplorerForExpression([NotNull] Type modelType, object model)
|
public ModelExplorer GetExplorerForExpression(Type modelType, object model)
|
||||||
{
|
{
|
||||||
|
if (modelType == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(modelType));
|
||||||
|
}
|
||||||
|
|
||||||
var metadata = _metadataProvider.GetMetadataForType(modelType);
|
var metadata = _metadataProvider.GetMetadataForType(modelType);
|
||||||
return GetExplorerForExpression(metadata, model);
|
return GetExplorerForExpression(metadata, model);
|
||||||
}
|
}
|
||||||
|
|
@ -309,8 +365,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// The returned <see cref="ModelExplorer"/> will have the current instance set as its <see cref="Container"/>.
|
/// The returned <see cref="ModelExplorer"/> will have the current instance set as its <see cref="Container"/>.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public ModelExplorer GetExplorerForExpression([NotNull] ModelMetadata metadata, object model)
|
public ModelExplorer GetExplorerForExpression(ModelMetadata metadata, object model)
|
||||||
{
|
{
|
||||||
|
if (metadata == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(metadata));
|
||||||
|
}
|
||||||
|
|
||||||
return new ModelExplorer(_metadataProvider, this, metadata, model);
|
return new ModelExplorer(_metadataProvider, this, metadata, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -331,8 +392,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// The returned <see cref="ModelExplorer"/> will have the current instance set as its <see cref="Container"/>.
|
/// The returned <see cref="ModelExplorer"/> will have the current instance set as its <see cref="Container"/>.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public ModelExplorer GetExplorerForExpression([NotNull] Type modelType, Func<object, object> modelAccessor)
|
public ModelExplorer GetExplorerForExpression(Type modelType, Func<object, object> modelAccessor)
|
||||||
{
|
{
|
||||||
|
if (modelType == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(modelType));
|
||||||
|
}
|
||||||
|
|
||||||
var metadata = _metadataProvider.GetMetadataForType(modelType);
|
var metadata = _metadataProvider.GetMetadataForType(modelType);
|
||||||
return GetExplorerForExpression(metadata, modelAccessor);
|
return GetExplorerForExpression(metadata, modelAccessor);
|
||||||
}
|
}
|
||||||
|
|
@ -354,8 +420,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// The returned <see cref="ModelExplorer"/> will have the current instance set as its <see cref="Container"/>.
|
/// The returned <see cref="ModelExplorer"/> will have the current instance set as its <see cref="Container"/>.
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public ModelExplorer GetExplorerForExpression([NotNull] ModelMetadata metadata, Func<object, object> modelAccessor)
|
public ModelExplorer GetExplorerForExpression(ModelMetadata metadata, Func<object, object> modelAccessor)
|
||||||
{
|
{
|
||||||
|
if (metadata == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(metadata));
|
||||||
|
}
|
||||||
|
|
||||||
return new ModelExplorer(_metadataProvider, this, metadata, modelAccessor);
|
return new ModelExplorer(_metadataProvider, this, metadata, modelAccessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4,9 +4,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Microsoft.Framework.Internal;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ViewFeatures
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extension methods for <see cref="ModelExplorer"/>.
|
/// Extension methods for <see cref="ModelExplorer"/>.
|
||||||
|
|
@ -19,8 +19,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="modelExplorer">The <see cref="ModelExplorer"/>.</param>
|
/// <param name="modelExplorer">The <see cref="ModelExplorer"/>.</param>
|
||||||
/// <returns>A simple display string for the model.</returns>
|
/// <returns>A simple display string for the model.</returns>
|
||||||
public static string GetSimpleDisplayText([NotNull] this ModelExplorer modelExplorer)
|
public static string GetSimpleDisplayText(this ModelExplorer modelExplorer)
|
||||||
{
|
{
|
||||||
|
if (modelExplorer == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(modelExplorer));
|
||||||
|
}
|
||||||
|
|
||||||
if (modelExplorer.Metadata.SimpleDisplayProperty != null)
|
if (modelExplorer.Metadata.SimpleDisplayProperty != null)
|
||||||
{
|
{
|
||||||
var propertyExplorer = modelExplorer.GetExplorerForProperty(
|
var propertyExplorer = modelExplorer.GetExplorerForProperty(
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
|
using Microsoft.AspNet.Mvc.ViewFeatures;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Rendering
|
namespace Microsoft.AspNet.Mvc.Rendering
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright (c) .NET Foundation. 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.ViewFeatures
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Extensions methods for <see cref="IModelMetadataProvider"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static class ModelMetadataProviderExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a <see cref="ModelExplorer"/> for the provided <paramref name="modelType"/> and
|
||||||
|
/// <paramref name="model"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="provider">The <see cref="IModelMetadataProvider"/>.</param>
|
||||||
|
/// <param name="modelType">The declared <see cref="Type"/> of the model object.</param>
|
||||||
|
/// <param name="model">The model object.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="ModelExplorer"/> for the <paramref name="modelType"/> and <paramref name="model"/>.
|
||||||
|
/// </returns>
|
||||||
|
public static ModelExplorer GetModelExplorerForType(
|
||||||
|
this IModelMetadataProvider provider,
|
||||||
|
Type modelType,
|
||||||
|
object model)
|
||||||
|
{
|
||||||
|
if (provider == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(provider));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modelType == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(modelType));
|
||||||
|
}
|
||||||
|
|
||||||
|
var modelMetadata = provider.GetMetadataForType(modelType);
|
||||||
|
return new ModelExplorer(provider, modelMetadata, model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ViewFeatures
|
namespace Microsoft.AspNet.Mvc.ViewFeatures
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -415,10 +415,7 @@ namespace System.Web.Http
|
||||||
/// </param>
|
/// </param>
|
||||||
public void Validate<TEntity>(TEntity entity, string keyPrefix)
|
public void Validate<TEntity>(TEntity entity, string keyPrefix)
|
||||||
{
|
{
|
||||||
var modelExplorer = MetadataProvider.GetModelExplorerForType(typeof(TEntity), entity);
|
|
||||||
|
|
||||||
var validatidationState = new ValidationStateDictionary();
|
var validatidationState = new ValidationStateDictionary();
|
||||||
|
|
||||||
ObjectValidator.Validate(
|
ObjectValidator.Validate(
|
||||||
BindingContext.ValidatorProvider,
|
BindingContext.ValidatorProvider,
|
||||||
ModelState,
|
ModelState,
|
||||||
|
|
|
||||||
|
|
@ -1240,14 +1240,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
||||||
|
|
||||||
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
||||||
var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(Person), model);
|
var metadata = metadataProvider.GetMetadataForType(typeof(Person));
|
||||||
var propertyMetadata = bindingContext.ModelMetadata.Properties[nameof(model.PropertyWithDefaultValue)];
|
var propertyMetadata = metadata.Properties[nameof(model.PropertyWithDefaultValue)];
|
||||||
|
|
||||||
var result = ModelBindingResult.Failed("foo");
|
var result = ModelBindingResult.Failed("foo");
|
||||||
var testableBinder = new TestableMutableObjectModelBinder();
|
var testableBinder = new TestableMutableObjectModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
testableBinder.SetProperty(bindingContext, modelExplorer, propertyMetadata, result);
|
testableBinder.SetProperty(bindingContext, metadata, propertyMetadata, result);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var person = Assert.IsType<Person>(bindingContext.Model);
|
var person = Assert.IsType<Person>(bindingContext.Model);
|
||||||
|
|
@ -1263,8 +1263,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
||||||
|
|
||||||
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
||||||
var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(Person), model);
|
var metadata = metadataProvider.GetMetadataForType(typeof(Person));
|
||||||
var propertyMetadata = bindingContext.ModelMetadata.Properties[nameof(model.PropertyWithInitializedValue)];
|
var propertyMetadata = metadata.Properties[nameof(model.PropertyWithInitializedValue)];
|
||||||
|
|
||||||
// The null model value won't be used because IsModelBound = false.
|
// The null model value won't be used because IsModelBound = false.
|
||||||
var result = ModelBindingResult.Failed("foo");
|
var result = ModelBindingResult.Failed("foo");
|
||||||
|
|
@ -1272,7 +1272,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
var testableBinder = new TestableMutableObjectModelBinder();
|
var testableBinder = new TestableMutableObjectModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
testableBinder.SetProperty(bindingContext, modelExplorer, propertyMetadata, result);
|
testableBinder.SetProperty(bindingContext, metadata, propertyMetadata, result);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var person = Assert.IsType<Person>(bindingContext.Model);
|
var person = Assert.IsType<Person>(bindingContext.Model);
|
||||||
|
|
@ -1288,9 +1288,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
||||||
|
|
||||||
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
||||||
var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(Person), model);
|
var metadata = metadataProvider.GetMetadataForType(typeof(Person));
|
||||||
var propertyMetadata =
|
var propertyMetadata = metadata.Properties[nameof(model.PropertyWithInitializedValueAndDefault)];
|
||||||
bindingContext.ModelMetadata.Properties[nameof(model.PropertyWithInitializedValueAndDefault)];
|
|
||||||
|
|
||||||
// The null model value won't be used because IsModelBound = false.
|
// The null model value won't be used because IsModelBound = false.
|
||||||
var result = ModelBindingResult.Failed("foo");
|
var result = ModelBindingResult.Failed("foo");
|
||||||
|
|
@ -1298,7 +1297,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
var testableBinder = new TestableMutableObjectModelBinder();
|
var testableBinder = new TestableMutableObjectModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
testableBinder.SetProperty(bindingContext, modelExplorer, propertyMetadata, result);
|
testableBinder.SetProperty(bindingContext, metadata, propertyMetadata, result);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var person = Assert.IsType<Person>(bindingContext.Model);
|
var person = Assert.IsType<Person>(bindingContext.Model);
|
||||||
|
|
@ -1314,14 +1313,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
||||||
|
|
||||||
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
||||||
var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(Person), model);
|
var metadata = metadataProvider.GetMetadataForType(typeof(Person));
|
||||||
var propertyMetadata = bindingContext.ModelMetadata.Properties[nameof(model.NonUpdateableProperty)];
|
var propertyMetadata = metadata.Properties[nameof(model.NonUpdateableProperty)];
|
||||||
|
|
||||||
var result = ModelBindingResult.Failed("foo");
|
var result = ModelBindingResult.Failed("foo");
|
||||||
var testableBinder = new TestableMutableObjectModelBinder();
|
var testableBinder = new TestableMutableObjectModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
testableBinder.SetProperty(bindingContext, modelExplorer, propertyMetadata, result);
|
testableBinder.SetProperty(bindingContext, metadata, propertyMetadata, result);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
// If didn't throw, success!
|
// If didn't throw, success!
|
||||||
|
|
@ -1351,7 +1350,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
[MemberData(nameof(MyCanUpdateButCannotSetPropertyData))]
|
[MemberData(nameof(MyCanUpdateButCannotSetPropertyData))]
|
||||||
public void SetProperty_ValueProvidedAndCanUpdatePropertyTrue_DoesNothing(
|
public void SetProperty_ValueProvidedAndCanUpdatePropertyTrue_DoesNothing(
|
||||||
string propertyName,
|
string propertyName,
|
||||||
Func<object, object> propertAccessor)
|
Func<object, object> propertyAccessor)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var model = new MyModelTestingCanUpdateProperty();
|
var model = new MyModelTestingCanUpdateProperty();
|
||||||
|
|
@ -1359,7 +1358,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
var bindingContext = CreateContext(GetMetadataForType(type), model);
|
var bindingContext = CreateContext(GetMetadataForType(type), model);
|
||||||
var modelState = bindingContext.ModelState;
|
var modelState = bindingContext.ModelState;
|
||||||
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
||||||
var modelExplorer = metadataProvider.GetModelExplorerForType(type, model);
|
var metadata = metadataProvider.GetMetadataForType(type);
|
||||||
|
|
||||||
var propertyMetadata = bindingContext.ModelMetadata.Properties[propertyName];
|
var propertyMetadata = bindingContext.ModelMetadata.Properties[propertyName];
|
||||||
var result = ModelBindingResult.Success(
|
var result = ModelBindingResult.Success(
|
||||||
|
|
@ -1369,10 +1368,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
var testableBinder = new TestableMutableObjectModelBinder();
|
var testableBinder = new TestableMutableObjectModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
testableBinder.SetProperty(bindingContext, modelExplorer, propertyMetadata, result);
|
testableBinder.SetProperty(bindingContext, metadata, propertyMetadata, result);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal("Joe", propertAccessor(model));
|
Assert.Equal("Joe", propertyAccessor(model));
|
||||||
Assert.True(modelState.IsValid);
|
Assert.True(modelState.IsValid);
|
||||||
Assert.Empty(modelState);
|
Assert.Empty(modelState);
|
||||||
}
|
}
|
||||||
|
|
@ -1436,14 +1435,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
var bindingContext = CreateContext(GetMetadataForType(type), model);
|
var bindingContext = CreateContext(GetMetadataForType(type), model);
|
||||||
var modelState = bindingContext.ModelState;
|
var modelState = bindingContext.ModelState;
|
||||||
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
||||||
var modelExplorer = metadataProvider.GetModelExplorerForType(type, model);
|
var metadata = metadataProvider.GetMetadataForType(type);
|
||||||
|
|
||||||
var propertyMetadata = bindingContext.ModelMetadata.Properties[propertyName];
|
var propertyMetadata = bindingContext.ModelMetadata.Properties[propertyName];
|
||||||
var result = ModelBindingResult.Success(propertyName, collection);
|
var result = ModelBindingResult.Success(propertyName, collection);
|
||||||
var testableBinder = new TestableMutableObjectModelBinder();
|
var testableBinder = new TestableMutableObjectModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
testableBinder.SetProperty(bindingContext, modelExplorer, propertyMetadata, result);
|
testableBinder.SetProperty(bindingContext, metadata, propertyMetadata, result);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(collection, propertyAccessor(model));
|
Assert.Equal(collection, propertyAccessor(model));
|
||||||
|
|
@ -1459,14 +1458,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
||||||
|
|
||||||
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
||||||
var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(Person), model);
|
var metadata = metadataProvider.GetMetadataForType(typeof(Person));
|
||||||
var propertyMetadata = bindingContext.ModelMetadata.Properties[nameof(model.DateOfBirth)];
|
var propertyMetadata = bindingContext.ModelMetadata.Properties[nameof(model.DateOfBirth)];
|
||||||
|
|
||||||
var result = ModelBindingResult.Success("foo", new DateTime(2001, 1, 1));
|
var result = ModelBindingResult.Success("foo", new DateTime(2001, 1, 1));
|
||||||
var testableBinder = new TestableMutableObjectModelBinder();
|
var testableBinder = new TestableMutableObjectModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
testableBinder.SetProperty(bindingContext, modelExplorer, propertyMetadata, result);
|
testableBinder.SetProperty(bindingContext, metadata, propertyMetadata, result);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(bindingContext.ModelState.IsValid);
|
Assert.True(bindingContext.ModelState.IsValid);
|
||||||
|
|
@ -1486,14 +1485,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
||||||
|
|
||||||
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
||||||
var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(Person), model);
|
var metadata = metadataProvider.GetMetadataForType(typeof(Person));
|
||||||
var propertyMetadata = bindingContext.ModelMetadata.Properties[nameof(model.DateOfDeath)];
|
var propertyMetadata = bindingContext.ModelMetadata.Properties[nameof(model.DateOfDeath)];
|
||||||
|
|
||||||
var result = ModelBindingResult.Success("foo", new DateTime(1800, 1, 1));
|
var result = ModelBindingResult.Success("foo", new DateTime(1800, 1, 1));
|
||||||
var testableBinder = new TestableMutableObjectModelBinder();
|
var testableBinder = new TestableMutableObjectModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
testableBinder.SetProperty(bindingContext, modelExplorer, propertyMetadata, result);
|
testableBinder.SetProperty(bindingContext, metadata, propertyMetadata, result);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal("Date of death can't be before date of birth." + Environment.NewLine
|
Assert.Equal("Date of death can't be before date of birth." + Environment.NewLine
|
||||||
|
|
@ -1511,14 +1510,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
var bindingContext = CreateContext(GetMetadataForType(model.GetType()), model);
|
||||||
|
|
||||||
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
||||||
var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(Person), model);
|
var metadata = metadataProvider.GetMetadataForType(typeof(Person));
|
||||||
var propertyMetadata = bindingContext.ModelMetadata.Properties[nameof(model.DateOfBirth)];
|
var propertyMetadata = bindingContext.ModelMetadata.Properties[nameof(model.DateOfBirth)];
|
||||||
|
|
||||||
var result = ModelBindingResult.Success("foo.DateOfBirth", model: null);
|
var result = ModelBindingResult.Success("foo.DateOfBirth", model: null);
|
||||||
var testableBinder = new TestableMutableObjectModelBinder();
|
var testableBinder = new TestableMutableObjectModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
testableBinder.SetProperty(bindingContext, modelExplorer, propertyMetadata, result);
|
testableBinder.SetProperty(bindingContext, metadata, propertyMetadata, result);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(bindingContext.ModelState.IsValid);
|
Assert.False(bindingContext.ModelState.IsValid);
|
||||||
|
|
@ -1539,14 +1538,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
bindingContext.ModelName = "foo";
|
bindingContext.ModelName = "foo";
|
||||||
|
|
||||||
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
var metadataProvider = bindingContext.OperationBindingContext.MetadataProvider;
|
||||||
var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(ModelWhosePropertySetterThrows), model);
|
var metadata = metadataProvider.GetMetadataForType(typeof(ModelWhosePropertySetterThrows));
|
||||||
var propertyMetadata = bindingContext.ModelMetadata.Properties[nameof(model.NameNoAttribute)];
|
var propertyMetadata = bindingContext.ModelMetadata.Properties[nameof(model.NameNoAttribute)];
|
||||||
|
|
||||||
var result = ModelBindingResult.Success("foo.NameNoAttribute", model: null);
|
var result = ModelBindingResult.Success("foo.NameNoAttribute", model: null);
|
||||||
var testableBinder = new TestableMutableObjectModelBinder();
|
var testableBinder = new TestableMutableObjectModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
testableBinder.SetProperty(bindingContext, modelExplorer, propertyMetadata, result);
|
testableBinder.SetProperty(bindingContext, metadata, propertyMetadata, result);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(bindingContext.ModelState.IsValid);
|
Assert.False(bindingContext.ModelState.IsValid);
|
||||||
|
|
@ -1898,11 +1897,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
|
||||||
public new void SetProperty(
|
public new void SetProperty(
|
||||||
ModelBindingContext bindingContext,
|
ModelBindingContext bindingContext,
|
||||||
ModelExplorer modelExplorer,
|
ModelMetadata metadata,
|
||||||
ModelMetadata propertyMetadata,
|
ModelMetadata propertyMetadata,
|
||||||
ModelBindingResult result)
|
ModelBindingResult result)
|
||||||
{
|
{
|
||||||
base.SetProperty(bindingContext, modelExplorer, propertyMetadata, result);
|
base.SetProperty(bindingContext, metadata, propertyMetadata, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
private static IModelMetadataProvider _metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
|
private static IModelMetadataProvider _metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ValuesSet()
|
public void Constructor_SetsAttribute()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var attribute = new RequiredAttribute();
|
var attribute = new RequiredAttribute();
|
||||||
|
|
@ -33,29 +33,35 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
Assert.Same(attribute, validator.Attribute);
|
Assert.Same(attribute, validator.Attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<object[]> ValidateSetsMemberNamePropertyDataSet
|
public static IEnumerable<object[]> Validate_SetsMemberName_OnValidationContext_ForProperties_Data
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
yield return new object[]
|
yield return new object[]
|
||||||
{
|
{
|
||||||
_metadataProvider.GetModelExplorerForType(typeof(string), "Hello").GetExplorerForProperty("Length"),
|
_metadataProvider.GetMetadataForType(typeof(string)).Properties["Length"],
|
||||||
"Length"
|
"Hello",
|
||||||
|
"Hello".Length,
|
||||||
|
"Length",
|
||||||
};
|
};
|
||||||
|
|
||||||
yield return new object[]
|
yield return new object[]
|
||||||
{
|
{
|
||||||
_metadataProvider.GetModelExplorerForType(typeof(SampleModel), 15),
|
_metadataProvider.GetMetadataForType(typeof(SampleModel)),
|
||||||
"SampleModel"
|
null,
|
||||||
|
15,
|
||||||
|
"SampleModel",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DNX451
|
#if DNX451
|
||||||
[Theory]
|
[Theory]
|
||||||
[MemberData(nameof(ValidateSetsMemberNamePropertyDataSet))]
|
[MemberData(nameof(Validate_SetsMemberName_OnValidationContext_ForProperties_Data))]
|
||||||
public void ValidateSetsMemberNamePropertyOfValidationContextForProperties(
|
public void Validate_SetsMemberName_OnValidationContext_ForProperties(
|
||||||
ModelExplorer modelExplorer,
|
ModelMetadata metadata,
|
||||||
|
object container,
|
||||||
|
object model,
|
||||||
string expectedMemberName)
|
string expectedMemberName)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|
@ -69,7 +75,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
.Returns(ValidationResult.Success)
|
.Returns(ValidationResult.Success)
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
||||||
var validationContext = CreateValidationContext(modelExplorer);
|
var validationContext = new ModelValidationContext()
|
||||||
|
{
|
||||||
|
Metadata = metadata,
|
||||||
|
Container = container,
|
||||||
|
Model = model,
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var results = validator.Validate(validationContext);
|
var results = validator.Validate(validationContext);
|
||||||
|
|
@ -80,18 +91,23 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ValidateWithIsValidTrue()
|
public void Validate_Valid()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var modelExplorer = _metadataProvider
|
var metadata = _metadataProvider.GetMetadataForType(typeof(string));
|
||||||
.GetModelExplorerForType(typeof(string), "Hello")
|
var container = "Hello";
|
||||||
.GetExplorerForProperty("Length");
|
var model = container.Length;
|
||||||
|
|
||||||
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
||||||
attribute.Setup(a => a.IsValid(modelExplorer.Model)).Returns(true);
|
attribute.Setup(a => a.IsValid(model)).Returns(true);
|
||||||
|
|
||||||
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
||||||
var validationContext = CreateValidationContext(modelExplorer);
|
var validationContext = new ModelValidationContext()
|
||||||
|
{
|
||||||
|
Metadata = metadata,
|
||||||
|
Container = container,
|
||||||
|
Model = model,
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = validator.Validate(validationContext);
|
var result = validator.Validate(validationContext);
|
||||||
|
|
@ -101,18 +117,23 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ValidateWithIsValidFalse()
|
public void Validate_Invalid()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var modelExplorer = _metadataProvider
|
var metadata = _metadataProvider.GetMetadataForProperty(typeof(string), "Length");
|
||||||
.GetModelExplorerForType(typeof(string), "Hello")
|
var container = "Hello";
|
||||||
.GetExplorerForProperty("Length");
|
var model = container.Length;
|
||||||
|
|
||||||
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
||||||
attribute.Setup(a => a.IsValid(modelExplorer.Model)).Returns(false);
|
attribute.Setup(a => a.IsValid(model)).Returns(false);
|
||||||
|
|
||||||
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
||||||
var validationContext = CreateValidationContext(modelExplorer);
|
var validationContext = new ModelValidationContext()
|
||||||
|
{
|
||||||
|
Metadata = metadata,
|
||||||
|
Container = container,
|
||||||
|
Model = model,
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = validator.Validate(validationContext);
|
var result = validator.Validate(validationContext);
|
||||||
|
|
@ -124,19 +145,24 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ValidatateWithValidationResultSuccess()
|
public void Validatate_ValidationResultSuccess()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var modelExplorer = _metadataProvider
|
var metadata = _metadataProvider.GetMetadataForType(typeof(string));
|
||||||
.GetModelExplorerForType(typeof(string), "Hello")
|
var container = "Hello";
|
||||||
.GetExplorerForProperty("Length");
|
var model = container.Length;
|
||||||
|
|
||||||
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
||||||
attribute.Protected()
|
attribute.Protected()
|
||||||
.Setup<ValidationResult>("IsValid", ItExpr.IsAny<object>(), ItExpr.IsAny<ValidationContext>())
|
.Setup<ValidationResult>("IsValid", ItExpr.IsAny<object>(), ItExpr.IsAny<ValidationContext>())
|
||||||
.Returns(ValidationResult.Success);
|
.Returns(ValidationResult.Success);
|
||||||
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
||||||
var validationContext = CreateValidationContext(modelExplorer);
|
var validationContext = new ModelValidationContext()
|
||||||
|
{
|
||||||
|
Metadata = metadata,
|
||||||
|
Container = container,
|
||||||
|
Model = model,
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = validator.Validate(validationContext);
|
var result = validator.Validate(validationContext);
|
||||||
|
|
@ -146,14 +172,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ValidateReturnsSingleValidationResultIfMemberNameSequenceIsEmpty()
|
public void Validate_ReturnsSingleValidationResult_IfMemberNameSequenceIsEmpty()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
const string errorMessage = "Some error message";
|
const string errorMessage = "Some error message";
|
||||||
|
|
||||||
var modelExplorer = _metadataProvider
|
var metadata = _metadataProvider.GetMetadataForType(typeof(string));
|
||||||
.GetModelExplorerForType(typeof(string), "Hello")
|
var container = "Hello";
|
||||||
.GetExplorerForProperty("Length");
|
var model = container.Length;
|
||||||
|
|
||||||
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
||||||
attribute.Protected()
|
attribute.Protected()
|
||||||
|
|
@ -161,24 +187,30 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
.Returns(new ValidationResult(errorMessage, memberNames: null));
|
.Returns(new ValidationResult(errorMessage, memberNames: null));
|
||||||
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
||||||
|
|
||||||
var validationContext = CreateValidationContext(modelExplorer);
|
var validationContext = new ModelValidationContext()
|
||||||
|
{
|
||||||
|
Metadata = metadata,
|
||||||
|
Container = container,
|
||||||
|
Model = model,
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var results = validator.Validate(validationContext);
|
var results = validator.Validate(validationContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
ModelValidationResult validationResult = Assert.Single(results);
|
var validationResult = Assert.Single(results);
|
||||||
Assert.Equal(errorMessage, validationResult.Message);
|
Assert.Equal(errorMessage, validationResult.Message);
|
||||||
Assert.Empty(validationResult.MemberName);
|
Assert.Empty(validationResult.MemberName);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ValidateReturnsSingleValidationResultIfOneMemberNameIsSpecified()
|
public void Validate_ReturnsSingleValidationResult_IfOneMemberNameIsSpecified()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
const string errorMessage = "A different error message";
|
const string errorMessage = "A different error message";
|
||||||
|
|
||||||
var modelExplorer = _metadataProvider.GetModelExplorerForType(typeof(object), new object());
|
var metadata = _metadataProvider.GetMetadataForType(typeof(object));
|
||||||
|
var model = new object();
|
||||||
|
|
||||||
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
||||||
attribute.Protected()
|
attribute.Protected()
|
||||||
|
|
@ -186,7 +218,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
.Returns(new ValidationResult(errorMessage, new[] { "FirstName" }));
|
.Returns(new ValidationResult(errorMessage, new[] { "FirstName" }));
|
||||||
|
|
||||||
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
||||||
var validationContext = CreateValidationContext(modelExplorer);
|
var validationContext = new ModelValidationContext()
|
||||||
|
{
|
||||||
|
Metadata = metadata,
|
||||||
|
Model = model,
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var results = validator.Validate(validationContext);
|
var results = validator.Validate(validationContext);
|
||||||
|
|
@ -198,10 +234,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ValidateReturnsMemberNameIfItIsDifferentFromDisplayName()
|
public void Validate_ReturnsMemberName_IfItIsDifferentFromDisplayName()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var modelExplorer = _metadataProvider.GetModelExplorerForType(typeof(SampleModel), new SampleModel());
|
var metadata = _metadataProvider.GetMetadataForType(typeof(SampleModel));
|
||||||
|
var model = new SampleModel();
|
||||||
|
|
||||||
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
||||||
attribute.Protected()
|
attribute.Protected()
|
||||||
|
|
@ -209,7 +246,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
.Returns(new ValidationResult("Name error", new[] { "Name" }));
|
.Returns(new ValidationResult("Name error", new[] { "Name" }));
|
||||||
|
|
||||||
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer: null);
|
||||||
var validationContext = CreateValidationContext(modelExplorer);
|
var validationContext = new ModelValidationContext()
|
||||||
|
{
|
||||||
|
Metadata = metadata,
|
||||||
|
Model = model,
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var results = validator.Validate(validationContext);
|
var results = validator.Validate(validationContext);
|
||||||
|
|
@ -220,15 +261,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ValidateWithIsValidFalse_StringLocalizerReturnsLocalizerErrorMessage()
|
public void Validate_IsValidFalse_StringLocalizerReturnsLocalizerErrorMessage()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var modelExplorer = _metadataProvider
|
var metadata = _metadataProvider.GetMetadataForType(typeof(string));
|
||||||
.GetModelExplorerForType(typeof(string), "Hello")
|
var container = "Hello";
|
||||||
.GetExplorerForProperty("Length");
|
var model = container.Length;
|
||||||
|
|
||||||
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
var attribute = new Mock<ValidationAttribute> { CallBase = true };
|
||||||
attribute.Setup(a => a.IsValid(modelExplorer.Model)).Returns(false);
|
attribute.Setup(a => a.IsValid(model)).Returns(false);
|
||||||
|
|
||||||
attribute.Object.ErrorMessage = "Length";
|
attribute.Object.ErrorMessage = "Length";
|
||||||
|
|
||||||
|
|
@ -237,7 +278,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
stringLocalizer.Setup(s => s["Length"]).Returns(localizedString);
|
stringLocalizer.Setup(s => s["Length"]).Returns(localizedString);
|
||||||
|
|
||||||
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer.Object);
|
var validator = new DataAnnotationsModelValidator(attribute.Object, stringLocalizer.Object);
|
||||||
var validationContext = CreateValidationContext(modelExplorer);
|
var validationContext = new ModelValidationContext()
|
||||||
|
{
|
||||||
|
Metadata = metadata,
|
||||||
|
Container = container,
|
||||||
|
Model = model,
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = validator.Validate(validationContext);
|
var result = validator.Validate(validationContext);
|
||||||
|
|
@ -260,16 +306,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
|
||||||
.IsRequired);
|
.IsRequired);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ModelValidationContext CreateValidationContext(ModelExplorer modelExplorer)
|
|
||||||
{
|
|
||||||
return new ModelValidationContext()
|
|
||||||
{
|
|
||||||
Container = modelExplorer.Container,
|
|
||||||
Metadata = modelExplorer.Metadata,
|
|
||||||
Model = modelExplorer.Model,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private class DerivedRequiredAttribute : RequiredAttribute
|
private class DerivedRequiredAttribute : RequiredAttribute
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,9 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Mvc.TestCommon;
|
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
|
using Microsoft.AspNet.Mvc.TestCommon;
|
||||||
|
using Microsoft.AspNet.Mvc.ViewFeatures;
|
||||||
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
using Microsoft.AspNet.Mvc.TestCommon;
|
using Microsoft.AspNet.Mvc.TestCommon;
|
||||||
|
using Microsoft.AspNet.Mvc.ViewFeatures;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Core
|
namespace Microsoft.AspNet.Mvc.Core
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ViewFeatures
|
||||||
{
|
{
|
||||||
public class ModelExplorerExtensionsTest
|
public class ModelExplorerExtensionsTest
|
||||||
{
|
{
|
||||||
|
|
@ -2,9 +2,10 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ViewFeatures
|
||||||
{
|
{
|
||||||
public class ModelExplorerTest
|
public class ModelExplorerTest
|
||||||
{
|
{
|
||||||
Loading…
Reference in New Issue