Replace IModelBindingMessageProvider with new highly-virtual base class (#6241)

Replace IModelBindingMessageProvider with new highly-virtual base class. Fixes #6069
This commit is contained in:
Steve Sanderson 2017-05-10 16:02:18 +01:00 committed by GitHub
parent f68bea235c
commit 014a786b45
17 changed files with 276 additions and 251 deletions

View File

@ -8,62 +8,62 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
/// <summary>
/// Provider for error messages the model binding system detects.
/// </summary>
public interface IModelBindingMessageProvider
public abstract class ModelBindingMessageProvider
{
/// <summary>
/// Error message the model binding system adds when a property with an associated
/// <c>BindRequiredAttribute</c> is not bound.
/// </summary>
/// <value>Default <see cref="string"/> is "A value for the '{0}' property was not provided.".</value>
Func<string, string> MissingBindRequiredValueAccessor { get; }
public virtual Func<string, string> MissingBindRequiredValueAccessor { get; }
/// <summary>
/// Error message the model binding system adds when either the key or the value of a
/// <see cref="System.Collections.Generic.KeyValuePair{TKey, TValue}"/> is bound but not both.
/// </summary>
/// <value>Default <see cref="string"/> is "A value is required.".</value>
Func<string> MissingKeyOrValueAccessor { get; }
public virtual Func<string> MissingKeyOrValueAccessor { get; }
/// <summary>
/// Error message the model binding system adds when no value is provided for the request body,
/// but a value is required.
/// </summary>
/// <value>Default <see cref="string"/> is "A non-empty request body is required.".</value>
Func<string> MissingRequestBodyRequiredValueAccessor { get; }
public virtual Func<string> MissingRequestBodyRequiredValueAccessor { get; }
/// <summary>
/// Error message the model binding system adds when a <c>null</c> value is bound to a
/// non-<see cref="Nullable"/> property.
/// </summary>
/// <value>Default <see cref="string"/> is "The value '{0}' is invalid.".</value>
Func<string, string> ValueMustNotBeNullAccessor { get; }
public virtual Func<string, string> ValueMustNotBeNullAccessor { get; }
/// <summary>
/// Error message the model binding system adds when <see cref="ModelError.Exception"/> is of type
/// <see cref="FormatException"/> or <see cref="OverflowException"/> and value is known.
/// </summary>
/// <value>Default <see cref="string"/> is "The value '{0}' is not valid for {1}.".</value>
Func<string, string, string> AttemptedValueIsInvalidAccessor { get; }
public virtual Func<string, string, string> AttemptedValueIsInvalidAccessor { get; }
/// <summary>
/// Error message the model binding system adds when <see cref="ModelError.Exception"/> is of type
/// <see cref="FormatException"/> or <see cref="OverflowException"/> and value is unknown.
/// </summary>
/// <value>Default <see cref="string"/> is "The supplied value is invalid for {0}.".</value>
Func<string, string> UnknownValueIsInvalidAccessor { get; }
public virtual Func<string, string> UnknownValueIsInvalidAccessor { get; }
/// <summary>
/// Fallback error message HTML and tag helpers display when a property is invalid but the
/// <see cref="ModelError"/>s have <c>null</c> <see cref="ModelError.ErrorMessage"/>s.
/// </summary>
/// <value>Default <see cref="string"/> is "The value '{0}' is invalid.".</value>
Func<string, string> ValueIsInvalidAccessor { get; }
public virtual Func<string, string> ValueIsInvalidAccessor { get; }
/// <summary>
/// Error message HTML and tag helpers add for client-side validation of numeric formats. Visible in the
/// browser if the field for a <c>float</c> property (for example) does not have a correctly-formatted value.
/// </summary>
/// <value>Default <see cref="string"/> is "The field {0} must be a number.".</value>
Func<string, string> ValueMustBeANumberAccessor { get; }
public virtual Func<string, string> ValueMustBeANumberAccessor { get; }
}
}

View File

@ -256,9 +256,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public abstract bool IsRequired { get; }
/// <summary>
/// Gets the <see cref="IModelBindingMessageProvider"/> instance.
/// Gets the <see cref="Metadata.ModelBindingMessageProvider"/> instance.
/// </summary>
public abstract IModelBindingMessageProvider ModelBindingMessageProvider { get; }
public abstract ModelBindingMessageProvider ModelBindingMessageProvider { get; }
/// <summary>
/// Gets a value indicating where the current metadata should be ordered relative to other properties

View File

@ -1,7 +1,11 @@
[
{
"TypeId": "public interface Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.IModelBindingMessageProvider",
"MemberId": "System.Func<System.String> get_MissingRequestBodyRequiredValueAccessor()",
"Kind": "Addition"
"Kind": "Removal"
},
{
"TypeId": "public abstract class Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata : System.IEquatable<Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata>",
"MemberId": "public abstract Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.IModelBindingMessageProvider get_ModelBindingMessageProvider()",
"Kind": "Removal"
}
]

View File

@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
/// </summary>
public class BindingMetadata
{
private ModelBindingMessageProvider _messageProvider;
private DefaultModelBindingMessageProvider _messageProvider;
/// <summary>
/// Gets or sets the <see cref="ModelBinding.BindingSource"/>.
@ -53,10 +53,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
public bool? IsReadOnly { get; set; }
/// <summary>
/// Gets the <see cref="Metadata.ModelBindingMessageProvider"/> instance. See
/// Gets the <see cref="Metadata.DefaultModelBindingMessageProvider"/> instance. See
/// <see cref="ModelMetadata.ModelBindingMessageProvider"/>.
/// </summary>
public ModelBindingMessageProvider ModelBindingMessageProvider
public DefaultModelBindingMessageProvider ModelBindingMessageProvider
{
get
{

View File

@ -0,0 +1,196 @@
// 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.AspNetCore.Mvc.Core;
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
{
/// <summary>
/// Read / write <see cref="ModelBindingMessageProvider"/> implementation.
/// </summary>
public class DefaultModelBindingMessageProvider : ModelBindingMessageProvider
{
private Func<string, string> _missingBindRequiredValueAccessor;
private Func<string> _missingKeyOrValueAccessor;
private Func<string> _missingRequestBodyRequiredValueAccessor;
private Func<string, string> _valueMustNotBeNullAccessor;
private Func<string, string, string> _attemptedValueIsInvalidAccessor;
private Func<string, string> _unknownValueIsInvalidAccessor;
private Func<string, string> _valueIsInvalidAccessor;
private Func<string, string> _valueMustBeANumberAccessor;
/// <summary>
/// Initializes a new instance of the <see cref="DefaultModelBindingMessageProvider"/> class.
/// </summary>
public DefaultModelBindingMessageProvider()
{
SetMissingBindRequiredValueAccessor(Resources.FormatModelBinding_MissingBindRequiredMember);
SetMissingKeyOrValueAccessor(Resources.FormatKeyValuePair_BothKeyAndValueMustBePresent);
SetMissingRequestBodyRequiredValueAccessor(Resources.FormatModelBinding_MissingRequestBodyRequiredMember);
SetValueMustNotBeNullAccessor(Resources.FormatModelBinding_NullValueNotValid);
SetAttemptedValueIsInvalidAccessor(Resources.FormatModelState_AttemptedValueIsInvalid);
SetUnknownValueIsInvalidAccessor(Resources.FormatModelState_UnknownValueIsInvalid);
SetValueIsInvalidAccessor(Resources.FormatHtmlGeneration_ValueIsInvalid);
SetValueMustBeANumberAccessor(Resources.FormatHtmlGeneration_ValueMustBeNumber);
}
/// <summary>
/// Initializes a new instance of the <see cref="DefaultModelBindingMessageProvider"/> class based on
/// <paramref name="originalProvider"/>.
/// </summary>
/// <param name="originalProvider">The <see cref="DefaultModelBindingMessageProvider"/> to duplicate.</param>
public DefaultModelBindingMessageProvider(DefaultModelBindingMessageProvider originalProvider)
{
if (originalProvider == null)
{
throw new ArgumentNullException(nameof(originalProvider));
}
SetMissingBindRequiredValueAccessor(originalProvider.MissingBindRequiredValueAccessor);
SetMissingKeyOrValueAccessor(originalProvider.MissingKeyOrValueAccessor);
SetMissingRequestBodyRequiredValueAccessor(originalProvider.MissingRequestBodyRequiredValueAccessor);
SetValueMustNotBeNullAccessor(originalProvider.ValueMustNotBeNullAccessor);
SetAttemptedValueIsInvalidAccessor(originalProvider.AttemptedValueIsInvalidAccessor);
SetUnknownValueIsInvalidAccessor(originalProvider.UnknownValueIsInvalidAccessor);
SetValueIsInvalidAccessor(originalProvider.ValueIsInvalidAccessor);
SetValueMustBeANumberAccessor(originalProvider.ValueMustBeANumberAccessor);
}
/// <inheritdoc/>
public override Func<string, string> MissingBindRequiredValueAccessor => _missingBindRequiredValueAccessor;
/// <summary>
/// Sets the <see cref="MissingBindRequiredValueAccessor"/> property.
/// </summary>
/// <param name="missingBindRequiredValueAccessor">The value to set.</param>
public void SetMissingBindRequiredValueAccessor(Func<string, string> missingBindRequiredValueAccessor)
{
if (missingBindRequiredValueAccessor == null)
{
throw new ArgumentNullException(nameof(missingBindRequiredValueAccessor));
}
_missingBindRequiredValueAccessor = missingBindRequiredValueAccessor;
}
/// <inheritdoc/>
public override Func<string> MissingKeyOrValueAccessor => _missingKeyOrValueAccessor;
/// <summary>
/// Sets the <see cref="MissingKeyOrValueAccessor"/> property.
/// </summary>
/// <param name="missingKeyOrValueAccessor">The value to set.</param>
public void SetMissingKeyOrValueAccessor(Func<string> missingKeyOrValueAccessor)
{
if (missingKeyOrValueAccessor == null)
{
throw new ArgumentNullException(nameof(missingKeyOrValueAccessor));
}
_missingKeyOrValueAccessor = missingKeyOrValueAccessor;
}
/// <inheritdoc/>
public override Func<string> MissingRequestBodyRequiredValueAccessor => _missingRequestBodyRequiredValueAccessor;
/// <summary>
/// Sets the <see cref="MissingRequestBodyRequiredValueAccessor"/> property.
/// </summary>
/// <param name="missingRequestBodyRequiredValueAccessor">The value to set.</param>
public void SetMissingRequestBodyRequiredValueAccessor(Func<string> missingRequestBodyRequiredValueAccessor)
{
if (missingRequestBodyRequiredValueAccessor == null)
{
throw new ArgumentNullException(nameof(missingRequestBodyRequiredValueAccessor));
}
_missingRequestBodyRequiredValueAccessor = missingRequestBodyRequiredValueAccessor;
}
/// <inheritdoc/>
public override Func<string, string> ValueMustNotBeNullAccessor => _valueMustNotBeNullAccessor;
/// <summary>
/// Sets the <see cref="ValueMustNotBeNullAccessor"/> property.
/// </summary>
/// <param name="valueMustNotBeNullAccessor">The value to set.</param>
public void SetValueMustNotBeNullAccessor(Func<string, string> valueMustNotBeNullAccessor)
{
if (valueMustNotBeNullAccessor == null)
{
throw new ArgumentNullException(nameof(valueMustNotBeNullAccessor));
}
_valueMustNotBeNullAccessor = valueMustNotBeNullAccessor;
}
/// <inheritdoc/>
public override Func<string, string, string> AttemptedValueIsInvalidAccessor => _attemptedValueIsInvalidAccessor;
/// <summary>
/// Sets the <see cref="AttemptedValueIsInvalidAccessor"/> property.
/// </summary>
/// <param name="attemptedValueIsInvalidAccessor">The value to set.</param>
public void SetAttemptedValueIsInvalidAccessor(Func<string, string, string> attemptedValueIsInvalidAccessor)
{
if (attemptedValueIsInvalidAccessor == null)
{
throw new ArgumentNullException(nameof(attemptedValueIsInvalidAccessor));
}
_attemptedValueIsInvalidAccessor = attemptedValueIsInvalidAccessor;
}
/// <inheritdoc/>
public override Func<string, string> UnknownValueIsInvalidAccessor => _unknownValueIsInvalidAccessor;
/// <summary>
/// Sets the <see cref="UnknownValueIsInvalidAccessor"/> property.
/// </summary>
/// <param name="unknownValueIsInvalidAccessor">The value to set.</param>
public void SetUnknownValueIsInvalidAccessor(Func<string, string> unknownValueIsInvalidAccessor)
{
if (unknownValueIsInvalidAccessor == null)
{
throw new ArgumentNullException(nameof(unknownValueIsInvalidAccessor));
}
_unknownValueIsInvalidAccessor = unknownValueIsInvalidAccessor;
}
/// <inheritdoc/>
public override Func<string, string> ValueIsInvalidAccessor => _valueIsInvalidAccessor;
/// <summary>
/// Sets the <see cref="ValueIsInvalidAccessor"/> property.
/// </summary>
/// <param name="valueIsInvalidAccessor">The value to set.</param>
public void SetValueIsInvalidAccessor(Func<string, string> valueIsInvalidAccessor)
{
if (valueIsInvalidAccessor == null)
{
throw new ArgumentNullException(nameof(valueIsInvalidAccessor));
}
_valueIsInvalidAccessor = valueIsInvalidAccessor;
}
/// <inheritdoc/>
public override Func<string, string> ValueMustBeANumberAccessor => _valueMustBeANumberAccessor;
/// <summary>
/// Sets the <see cref="ValueMustBeANumberAccessor"/> property.
/// </summary>
/// <param name="valueMustBeANumberAccessor">The value to set.</param>
public void SetValueMustBeANumberAccessor(Func<string, string> valueMustBeANumberAccessor)
{
if (valueMustBeANumberAccessor == null)
{
throw new ArgumentNullException(nameof(valueMustBeANumberAccessor));
}
_valueMustBeANumberAccessor = valueMustBeANumberAccessor;
}
}
}

View File

@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
// Default message provider for all DefaultModelMetadata instances; cloned before exposing to
// IBindingMetadataProvider instances to ensure customizations are not accidentally shared.
private readonly ModelBindingMessageProvider _modelBindingMessageProvider;
private readonly DefaultModelBindingMessageProvider _modelBindingMessageProvider;
private ReadOnlyDictionary<object, object> _additionalValues;
private ModelMetadata _elementMetadata;
@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
IModelMetadataProvider provider,
ICompositeMetadataDetailsProvider detailsProvider,
DefaultMetadataDetails details)
: this(provider, detailsProvider, details, new ModelBindingMessageProvider())
: this(provider, detailsProvider, details, new DefaultModelBindingMessageProvider())
{
}
@ -51,12 +51,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
/// <param name="provider">The <see cref="IModelMetadataProvider"/>.</param>
/// <param name="detailsProvider">The <see cref="ICompositeMetadataDetailsProvider"/>.</param>
/// <param name="details">The <see cref="DefaultMetadataDetails"/>.</param>
/// <param name="modelBindingMessageProvider">The <see cref="Metadata.ModelBindingMessageProvider"/>.</param>
/// <param name="modelBindingMessageProvider">The <see cref="Metadata.DefaultModelBindingMessageProvider"/>.</param>
public DefaultModelMetadata(
IModelMetadataProvider provider,
ICompositeMetadataDetailsProvider detailsProvider,
DefaultMetadataDetails details,
ModelBindingMessageProvider modelBindingMessageProvider)
DefaultModelBindingMessageProvider modelBindingMessageProvider)
: base(details.Key)
{
if (provider == null)
@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
// Provide a unique ModelBindingMessageProvider instance so providers' customizations are per-type.
context.BindingMetadata.ModelBindingMessageProvider =
new ModelBindingMessageProvider(_modelBindingMessageProvider);
new DefaultModelBindingMessageProvider(_modelBindingMessageProvider);
_detailsProvider.CreateBindingMetadata(context);
_details.BindingMetadata = context.BindingMetadata;
@ -440,7 +440,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
}
/// <inheritdoc />
public override IModelBindingMessageProvider ModelBindingMessageProvider
public override ModelBindingMessageProvider ModelBindingMessageProvider
{
get
{

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
/// </summary>
/// <param name="detailsProvider">The <see cref="ICompositeMetadataDetailsProvider"/>.</param>
public DefaultModelMetadataProvider(ICompositeMetadataDetailsProvider detailsProvider)
: this(detailsProvider, new ModelBindingMessageProvider())
: this(detailsProvider, new DefaultModelBindingMessageProvider())
{
}
@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
private DefaultModelMetadataProvider(
ICompositeMetadataDetailsProvider detailsProvider,
ModelBindingMessageProvider modelBindingMessageProvider)
DefaultModelBindingMessageProvider modelBindingMessageProvider)
{
if (detailsProvider == null)
{
@ -62,10 +62,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
protected ICompositeMetadataDetailsProvider DetailsProvider { get; }
/// <summary>
/// Gets the <see cref="Metadata.ModelBindingMessageProvider"/>.
/// Gets the <see cref="Metadata.DefaultModelBindingMessageProvider"/>.
/// </summary>
/// <value>Same as <see cref="MvcOptions.ModelBindingMessageProvider"/> in all production scenarios.</value>
protected ModelBindingMessageProvider ModelBindingMessageProvider { get; }
protected DefaultModelBindingMessageProvider ModelBindingMessageProvider { get; }
/// <inheritdoc />
public virtual IEnumerable<ModelMetadata> GetMetadataForProperties(Type modelType)
@ -110,7 +110,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
return cacheEntry.Metadata;
}
private static ModelBindingMessageProvider GetMessageProvider(IOptions<MvcOptions> optionsAccessor)
private static DefaultModelBindingMessageProvider GetMessageProvider(IOptions<MvcOptions> optionsAccessor)
{
if (optionsAccessor == null)
{

View File

@ -1,204 +0,0 @@
// 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.AspNetCore.Mvc.Core;
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
{
/// <summary>
/// Read / write <see cref="IModelBindingMessageProvider"/> implementation.
/// </summary>
public class ModelBindingMessageProvider : IModelBindingMessageProvider
{
private Func<string, string> _missingBindRequiredValueAccessor;
private Func<string> _missingKeyOrValueAccessor;
private Func<string> _missingRequestBodyRequiredValueAccessor;
private Func<string, string> _valueMustNotBeNullAccessor;
private Func<string, string, string> _attemptedValueIsInvalidAccessor;
private Func<string, string> _unknownValueIsInvalidAccessor;
private Func<string, string> _valueIsInvalidAccessor;
private Func<string, string> _valueMustBeANumberAccessor;
/// <summary>
/// Initializes a new instance of the <see cref="ModelBindingMessageProvider"/> class.
/// </summary>
public ModelBindingMessageProvider()
{
MissingBindRequiredValueAccessor = Resources.FormatModelBinding_MissingBindRequiredMember;
MissingKeyOrValueAccessor = Resources.FormatKeyValuePair_BothKeyAndValueMustBePresent;
MissingRequestBodyRequiredValueAccessor = Resources.FormatModelBinding_MissingRequestBodyRequiredMember;
ValueMustNotBeNullAccessor = Resources.FormatModelBinding_NullValueNotValid;
AttemptedValueIsInvalidAccessor = Resources.FormatModelState_AttemptedValueIsInvalid;
UnknownValueIsInvalidAccessor = Resources.FormatModelState_UnknownValueIsInvalid;
ValueIsInvalidAccessor = Resources.FormatHtmlGeneration_ValueIsInvalid;
ValueMustBeANumberAccessor = Resources.FormatHtmlGeneration_ValueMustBeNumber;
}
/// <summary>
/// Initializes a new instance of the <see cref="ModelBindingMessageProvider"/> class based on
/// <paramref name="originalProvider"/>.
/// </summary>
/// <param name="originalProvider">The <see cref="ModelBindingMessageProvider"/> to duplicate.</param>
public ModelBindingMessageProvider(ModelBindingMessageProvider originalProvider)
{
if (originalProvider == null)
{
throw new ArgumentNullException(nameof(originalProvider));
}
MissingBindRequiredValueAccessor = originalProvider.MissingBindRequiredValueAccessor;
MissingKeyOrValueAccessor = originalProvider.MissingKeyOrValueAccessor;
MissingRequestBodyRequiredValueAccessor = originalProvider.MissingRequestBodyRequiredValueAccessor;
ValueMustNotBeNullAccessor = originalProvider.ValueMustNotBeNullAccessor;
AttemptedValueIsInvalidAccessor = originalProvider.AttemptedValueIsInvalidAccessor;
UnknownValueIsInvalidAccessor = originalProvider.UnknownValueIsInvalidAccessor;
ValueIsInvalidAccessor = originalProvider.ValueIsInvalidAccessor;
ValueMustBeANumberAccessor = originalProvider.ValueMustBeANumberAccessor;
}
/// <inheritdoc/>
public Func<string, string> MissingBindRequiredValueAccessor
{
get
{
return _missingBindRequiredValueAccessor;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_missingBindRequiredValueAccessor = value;
}
}
/// <inheritdoc/>
public Func<string> MissingKeyOrValueAccessor
{
get
{
return _missingKeyOrValueAccessor;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_missingKeyOrValueAccessor = value;
}
}
/// <inheritdoc/>
public Func<string> MissingRequestBodyRequiredValueAccessor
{
get
{
return _missingRequestBodyRequiredValueAccessor;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_missingRequestBodyRequiredValueAccessor = value;
}
}
/// <inheritdoc/>
public Func<string, string> ValueMustNotBeNullAccessor
{
get
{
return _valueMustNotBeNullAccessor;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_valueMustNotBeNullAccessor = value;
}
}
/// <inheritdoc/>
public Func<string, string, string> AttemptedValueIsInvalidAccessor
{
get
{
return _attemptedValueIsInvalidAccessor;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_attemptedValueIsInvalidAccessor = value;
}
}
/// <inheritdoc/>
public Func<string, string> UnknownValueIsInvalidAccessor
{
get
{
return _unknownValueIsInvalidAccessor;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_unknownValueIsInvalidAccessor = value;
}
}
/// <inheritdoc/>
public Func<string, string> ValueIsInvalidAccessor
{
get
{
return _valueIsInvalidAccessor;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_valueIsInvalidAccessor = value;
}
}
/// <inheritdoc/>
public Func<string, string> ValueMustBeANumberAccessor
{
get
{
return _valueMustBeANumberAccessor;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_valueMustBeANumberAccessor = value;
}
}
}
}

View File

@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Mvc
InputFormatters = new FormatterCollection<IInputFormatter>();
OutputFormatters = new FormatterCollection<IOutputFormatter>();
ModelBinderProviders = new List<IModelBinderProvider>();
ModelBindingMessageProvider = new ModelBindingMessageProvider();
ModelBindingMessageProvider = new DefaultModelBindingMessageProvider();
ModelMetadataDetailsProviders = new List<IMetadataDetailsProvider>();
ModelValidatorProviders = new List<IModelValidatorProvider>();
ValueProviderFactories = new List<IValueProviderFactory>();
@ -98,11 +98,11 @@ namespace Microsoft.AspNetCore.Mvc
public IList<IModelBinderProvider> ModelBinderProviders { get; }
/// <summary>
/// Gets the default <see cref="IModelBindingMessageProvider"/>. Changes here are copied to the
/// Gets the default <see cref="ModelBinding.Metadata.ModelBindingMessageProvider"/>. Changes here are copied to the
/// <see cref="ModelMetadata.ModelBindingMessageProvider"/> property of all <see cref="ModelMetadata"/>
/// instances unless overridden in a custom <see cref="IBindingMetadataProvider"/>.
/// </summary>
public ModelBindingMessageProvider ModelBindingMessageProvider { get; }
public DefaultModelBindingMessageProvider ModelBindingMessageProvider { get; }
/// <summary>
/// Gets a list of <see cref="IMetadataDetailsProvider"/> instances that will be used to

View File

@ -121,5 +121,29 @@
"TypeId": "public abstract class Microsoft.AspNetCore.Mvc.ControllerBase",
"MemberId": "public virtual Microsoft.AspNetCore.Mvc.SignOutResult SignOut(Microsoft.AspNetCore.Http.Authentication.AuthenticationProperties properties, params System.String[] authenticationSchemes)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelBindingMessageProvider : Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.IModelBindingMessageProvider",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.AspNetCore.Mvc.MvcOptions",
"MemberId": "public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelBindingMessageProvider get_ModelBindingMessageProvider()",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.BindingMetadata",
"MemberId": "public Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelBindingMessageProvider get_ModelBindingMessageProvider()",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.BindingMetadata",
"MemberId": "public System.Void set_ModelBindingMessageProvider(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelBindingMessageProvider value)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.DefaultModelMetadata : Microsoft.AspNetCore.Mvc.ModelBinding.ModelMetadata",
"MemberId": "public override Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.IModelBindingMessageProvider get_ModelBindingMessageProvider()",
"Kind": "Removal"
}
]

View File

@ -527,7 +527,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
}
}
public override IModelBindingMessageProvider ModelBindingMessageProvider
public override ModelBindingMessageProvider ModelBindingMessageProvider
{
get
{

View File

@ -890,8 +890,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var bindingMetadataProvider = new DefaultBindingMetadataProvider();
var compositeProvider = new DefaultCompositeMetadataDetailsProvider(new[] { bindingMetadataProvider });
var optionsAccessor = new OptionsAccessor();
optionsAccessor.Value.ModelBindingMessageProvider.UnknownValueIsInvalidAccessor =
name => $"Hmm, the supplied value is not valid for { name }.";
optionsAccessor.Value.ModelBindingMessageProvider.SetUnknownValueIsInvalidAccessor(
name => $"Hmm, the supplied value is not valid for { name }.");
var provider = new DefaultModelMetadataProvider(compositeProvider, optionsAccessor);
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));
@ -935,8 +935,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var bindingMetadataProvider = new DefaultBindingMetadataProvider();
var compositeProvider = new DefaultCompositeMetadataDetailsProvider(new[] { bindingMetadataProvider });
var optionsAccessor = new OptionsAccessor();
optionsAccessor.Value.ModelBindingMessageProvider.AttemptedValueIsInvalidAccessor =
(value, name) => $"Hmm, the value '{ value }' is not valid for { name }.";
optionsAccessor.Value.ModelBindingMessageProvider.SetAttemptedValueIsInvalidAccessor(
(value, name) => $"Hmm, the value '{ value }' is not valid for { name }.");
var provider = new DefaultModelMetadataProvider(compositeProvider, optionsAccessor);
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));

View File

@ -131,8 +131,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Binders
provider.ForType<Person>().BindingDetails(d =>
{
d.BindingSource = BindingSource.Body;
d.ModelBindingMessageProvider.MissingRequestBodyRequiredValueAccessor =
() => "Customized error message";
d.ModelBindingMessageProvider.SetMissingRequestBodyRequiredValueAccessor(
() => "Customized error message");
});
var bindingContext = GetBindingContext(

View File

@ -45,8 +45,11 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var provider = new TestModelMetadataProvider();
provider
.ForProperty(typeof(TypeWithNumericProperty), nameof(TypeWithNumericProperty.Id))
.BindingDetails(d => d.ModelBindingMessageProvider.ValueMustBeANumberAccessor =
name => $"Error message about '{ name }' from override.");
.BindingDetails(d =>
{
d.ModelBindingMessageProvider.SetValueMustBeANumberAccessor(
name => $"Error message about '{ name }' from override.");
});
var metadata = provider.GetMetadataForProperty(
typeof(TypeWithNumericProperty),
nameof(TypeWithNumericProperty.Id));

View File

@ -1847,8 +1847,8 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
.BindingDetails((Action<ModelBinding.Metadata.BindingMetadata>)(binding =>
{
// A real details provider could customize message based on BindingMetadataProviderContext.
binding.ModelBindingMessageProvider.MissingBindRequiredValueAccessor =
name => $"Hurts when '{ name }' is not provided.";
binding.ModelBindingMessageProvider.SetMissingBindRequiredValueAccessor(
name => $"Hurts when '{ name }' is not provided.");
}));
var parameterBinder = ModelBindingTestHelper.GetParameterBinder(metadataProvider);

View File

@ -100,7 +100,8 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
.BindingDetails((System.Action<ModelBinding.Metadata.BindingMetadata>)(binding =>
{
// A real details provider could customize message based on BindingMetadataProviderContext.
binding.ModelBindingMessageProvider.MissingKeyOrValueAccessor = () => $"Hurts when nothing is provided.";
binding.ModelBindingMessageProvider.SetMissingKeyOrValueAccessor(
() => $"Hurts when nothing is provided.");
}));
var parameterBinder = ModelBindingTestHelper.GetParameterBinder(metadataProvider);
@ -183,7 +184,8 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
.BindingDetails((System.Action<ModelBinding.Metadata.BindingMetadata>)(binding =>
{
// A real details provider could customize message based on BindingMetadataProviderContext.
binding.ModelBindingMessageProvider.MissingKeyOrValueAccessor = () => $"Hurts when nothing is provided.";
binding.ModelBindingMessageProvider.SetMissingKeyOrValueAccessor(
() => $"Hurts when nothing is provided.");
}));
var parameterBinder = ModelBindingTestHelper.GetParameterBinder(metadataProvider);

View File

@ -256,8 +256,8 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
.BindingDetails(binding =>
{
// A real details provider could customize message based on BindingMetadataProviderContext.
binding.ModelBindingMessageProvider.AttemptedValueIsInvalidAccessor =
(value, name) => $"Hmm, '{ value }' is not a valid value for '{ name }'.";
binding.ModelBindingMessageProvider.SetAttemptedValueIsInvalidAccessor(
(value, name) => $"Hmm, '{ value }' is not a valid value for '{ name }'.");
});
var parameterBinder = ModelBindingTestHelper.GetParameterBinder(metadataProvider);
var parameter = new ParameterDescriptor()
@ -357,8 +357,8 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
.BindingDetails(binding =>
{
// A real details provider could customize message based on BindingMetadataProviderContext.
binding.ModelBindingMessageProvider.ValueMustNotBeNullAccessor =
value => $"Hurts when '{ value }' is provided.";
binding.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
value => $"Hurts when '{ value }' is provided.");
});
var parameterBinder = ModelBindingTestHelper.GetParameterBinder(metadataProvider);