Replace IModelBindingMessageProvider with new highly-virtual base class (#6241)
Replace IModelBindingMessageProvider with new highly-virtual base class. Fixes #6069
This commit is contained in:
parent
f68bea235c
commit
014a786b45
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
|
|
@ -527,7 +527,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
|
|||
}
|
||||
}
|
||||
|
||||
public override IModelBindingMessageProvider ModelBindingMessageProvider
|
||||
public override ModelBindingMessageProvider ModelBindingMessageProvider
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue