diff --git a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Metadata/ModelAttributes.cs b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Metadata/ModelAttributes.cs
index 0276163272..e5b59933ae 100644
--- a/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Metadata/ModelAttributes.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Core/ModelBinding/Metadata/ModelAttributes.cs
@@ -5,8 +5,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
-using Microsoft.AspNetCore.Mvc.Controllers;
-using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
namespace Microsoft.AspNetCore.Mvc.ModelBinding
{
@@ -56,7 +54,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
/// If this instance represents a parameter, the set of attributes for that parameter.
/// Otherwise, null .
///
- public ModelAttributes(IEnumerable typeAttributes, IEnumerable propertyAttributes, IEnumerable parameterAttributes)
+ internal ModelAttributes(
+ IEnumerable typeAttributes,
+ IEnumerable propertyAttributes,
+ IEnumerable parameterAttributes)
{
if (propertyAttributes != null)
{
@@ -73,7 +74,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
else if (parameterAttributes != null)
{
// Represents a parameter
- Attributes = ParameterAttributes = parameterAttributes.ToArray();
+ if (typeAttributes == null)
+ {
+ throw new ArgumentNullException(nameof(typeAttributes));
+ }
+
+ ParameterAttributes = parameterAttributes.ToArray();
+ TypeAttributes = typeAttributes.ToArray();
+ Attributes = ParameterAttributes.Concat(TypeAttributes).ToArray();
}
else if (typeAttributes != null)
{
@@ -89,7 +97,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
///
/// Gets the set of all attributes. If this instance represents the attributes for a property, the attributes
- /// on the property definition are before those on the property's .
+ /// on the property definition are before those on the property's . If this instance
+ /// represents the attributes for a parameter, the attributes on the parameter definition are before those on
+ /// the parameter's .
///
public IReadOnlyList Attributes { get; }
@@ -106,10 +116,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public IReadOnlyList ParameterAttributes { get; }
///
- /// Gets the set of attributes on the . If this instance represents a property,
- /// then contains attributes retrieved from
- /// . If this instance represents a parameter, then
- /// the value is null .
+ /// Gets the set of attributes on the . If this instance represents a property, then
+ /// contains attributes retrieved from .
+ /// If this instance represents a parameter, then contains attributes retrieved from
+ /// .
///
public IReadOnlyList TypeAttributes { get; }
@@ -120,7 +130,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
///
/// A for which attributes need to be resolved.
///
- /// A instance with the attributes of the property.
+ ///
+ /// A instance with the attributes of the property and its .
+ ///
public static ModelAttributes GetAttributesForProperty(Type type, PropertyInfo property)
{
if (type == null)
@@ -146,7 +158,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
}
}
- return new ModelAttributes(typeAttributes, propertyAttributes, null);
+ return new ModelAttributes(typeAttributes, propertyAttributes, parameterAttributes: null);
}
///
@@ -170,18 +182,27 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
attributes = attributes.Concat(metadataType.GetTypeInfo().GetCustomAttributes());
}
- return new ModelAttributes(attributes, null, null);
+ return new ModelAttributes(attributes, propertyAttributes: null, parameterAttributes: null);
}
///
/// Gets the attributes for the given .
///
- /// The for which attributes need to be resolved.
+ ///
+ /// The for which attributes need to be resolved.
///
- /// A instance with the attributes of the .
+ ///
+ /// A instance with the attributes of the parameter and its .
+ ///
public static ModelAttributes GetAttributesForParameter(ParameterInfo parameterInfo)
{
- return new ModelAttributes(null, null, parameterInfo.GetCustomAttributes());
+ // Prior versions called IModelMetadataProvider.GetMetadataForType(...) and therefore
+ // GetAttributesForType(...) for parameters. Maintain that set of attributes (including those from an
+ // ModelMetadataTypeAttribute reference) for back-compatibility.
+ var typeAttributes = GetAttributesForType(parameterInfo.ParameterType).TypeAttributes;
+ var parameterAttributes = parameterInfo.GetCustomAttributes();
+
+ return new ModelAttributes(typeAttributes, propertyAttributes: null, parameterAttributes);
}
private static Type GetMetadataType(Type type)
diff --git a/test/Microsoft.AspNetCore.Mvc.Abstractions.Test/ModelBinding/BindingInfoTest.cs b/test/Microsoft.AspNetCore.Mvc.Abstractions.Test/ModelBinding/BindingInfoTest.cs
index 3c83f948d8..cdd8d4570f 100644
--- a/test/Microsoft.AspNetCore.Mvc.Abstractions.Test/ModelBinding/BindingInfoTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Abstractions.Test/ModelBinding/BindingInfoTest.cs
@@ -176,7 +176,6 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
{
// Arrange
var attributes = new object[] { new ModelBinderAttribute(typeof(object)), new ControllerAttribute(), new BindNeverAttribute(), };
- var modelAttributes = new ModelAttributes(Enumerable.Empty(), null, null);
var propertyFilterProvider = Mock.Of();
var modelType = typeof(Guid);
var provider = new TestModelMetadataProvider();
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/DefaultBindingMetadataProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/DefaultBindingMetadataProviderTest.cs
index 327f8aa66f..7464e6203a 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/DefaultBindingMetadataProviderTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/Internal/DefaultBindingMetadataProviderTest.cs
@@ -279,7 +279,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var context = new BindingMetadataProviderContext(
ModelMetadataIdentity.ForParameter(ParameterInfos.SampleParameterInfo),
- new ModelAttributes(null, null, parameterAttributes));
+ new ModelAttributes(Array.Empty(), null, parameterAttributes));
var provider = new DefaultBindingMetadataProvider();
@@ -302,7 +302,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var context = new BindingMetadataProviderContext(
ModelMetadataIdentity.ForParameter(ParameterInfos.SampleParameterInfo),
- new ModelAttributes(null, null, parameterAttributes));
+ new ModelAttributes(Array.Empty(), null, parameterAttributes));
var provider = new DefaultBindingMetadataProvider();
@@ -325,7 +325,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var context = new BindingMetadataProviderContext(
ModelMetadataIdentity.ForParameter(ParameterInfos.SampleParameterInfo),
- new ModelAttributes(null, null, parameterAttributes));
+ new ModelAttributes(Array.Empty(), null, parameterAttributes));
var provider = new DefaultBindingMetadataProvider();
@@ -348,7 +348,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var context = new BindingMetadataProviderContext(
ModelMetadataIdentity.ForParameter(ParameterInfos.SampleParameterInfo),
- new ModelAttributes(null, null, parameterAttributes));
+ new ModelAttributes(Array.Empty(), null, parameterAttributes));
var provider = new DefaultBindingMetadataProvider();
@@ -371,7 +371,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var context = new BindingMetadataProviderContext(
ModelMetadataIdentity.ForParameter(ParameterInfos.SampleParameterInfo),
- new ModelAttributes(null, null, parameterAttributes));
+ new ModelAttributes(Array.Empty(), null, parameterAttributes));
var provider = new DefaultBindingMetadataProvider();
@@ -395,7 +395,7 @@ namespace Microsoft.AspNetCore.Mvc.Internal
var context = new BindingMetadataProviderContext(
ModelMetadataIdentity.ForParameter(ParameterInfos.SampleParameterInfo),
- new ModelAttributes(null, null, parameterAttributes));
+ new ModelAttributes(Array.Empty(), null, parameterAttributes));
var provider = new DefaultBindingMetadataProvider();
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/JQueryQueryStringValueProviderFactoryTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/JQueryQueryStringValueProviderFactoryTest.cs
index 70c3edc6a2..fe6a060d92 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/JQueryQueryStringValueProviderFactoryTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/JQueryQueryStringValueProviderFactoryTest.cs
@@ -17,12 +17,6 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Test
{
private static readonly Dictionary _backingStore = new Dictionary
{
- // Reviewers: A fair number of cases in the following dataset seem impossible for jQuery.ajax() to send
- // given how $.ajax() and $.param() are defined i.e. $.param() won't add a bare name after ']'. Also, the
- // names we generate for elements are always valid. Should we remove these weird / invalid cases
- // e.g. normalizing "property[]Value"? (That normalizes to "propertyValue".) See also
- // https://github.com/jquery/jquery/blob/1ea092a54b00aa4d902f4e22ada3854d195d4a18/src/serialize.js#L13-L92
- // The alternative is to handle "[]name" and "[index]name" cases while normalizing keys.
{ "[]", new[] { "found" } },
{ "[]property1", new[] { "found" } },
{ "property2[]", new[] { "found" } },
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/Metadata/DefaultModelMetadataProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/Metadata/DefaultModelMetadataProviderTest.cs
index fd5e9fa75d..4286f263c9 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/Metadata/DefaultModelMetadataProviderTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/Metadata/DefaultModelMetadataProviderTest.cs
@@ -212,7 +212,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
// Assert
var defaultMetadata = Assert.IsType(metadata);
- Assert.Empty(defaultMetadata.Attributes.Attributes);
+
+ // Not exactly "no attributes" due to SerializableAttribute on object.
+ Assert.IsType(Assert.Single(defaultMetadata.Attributes.Attributes));
}
[Fact]
@@ -229,11 +231,19 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
// Assert
var defaultMetadata = Assert.IsType(metadata);
- Assert.Equal(2, defaultMetadata.Attributes.Attributes.Count);
- var attribute1 = Assert.IsType(defaultMetadata.Attributes.Attributes[0]);
- Assert.Equal("ParamAttrib1", attribute1.Value);
- var attribute2 = Assert.IsType(defaultMetadata.Attributes.Attributes[1]);
- Assert.Equal("ParamAttrib2", attribute2.Value);
+ Assert.Collection(
+ // Take(2) to ignore SerializableAttribute on object.
+ defaultMetadata.Attributes.Attributes.Take(2),
+ attribute =>
+ {
+ var modelAttribute = Assert.IsType(attribute);
+ Assert.Equal("ParamAttrib1", modelAttribute.Value);
+ },
+ attribute =>
+ {
+ var modelAttribute = Assert.IsType(attribute);
+ Assert.Equal("ParamAttrib2", modelAttribute.Value);
+ });
}
[Fact]
diff --git a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/Metadata/ModelAttributesTest.cs b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/Metadata/ModelAttributesTest.cs
index 69c146726e..3b0b3b0d92 100644
--- a/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/Metadata/ModelAttributesTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Core.Test/ModelBinding/Metadata/ModelAttributesTest.cs
@@ -5,6 +5,7 @@ using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
+using System.Runtime.CompilerServices;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.ModelBinding
@@ -188,10 +189,11 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
.GetParameters()[0]);
// Assert
- Assert.Empty(attributes.Attributes);
+ // Not exactly "no attributes" due to SerializableAttribute on object.
+ Assert.IsType(Assert.Single(attributes.Attributes));
Assert.Empty(attributes.ParameterAttributes);
- Assert.Null(attributes.TypeAttributes);
Assert.Null(attributes.PropertyAttributes);
+ Assert.Equal(attributes.Attributes, attributes.TypeAttributes);
}
[Fact]
@@ -204,12 +206,40 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
.GetParameters()[1]);
// Assert
- Assert.IsType(attributes.Attributes[0]);
- Assert.IsType(attributes.Attributes[1]);
- Assert.IsType(attributes.ParameterAttributes[0]);
- Assert.IsType(attributes.ParameterAttributes[1]);
- Assert.Null(attributes.TypeAttributes);
+ Assert.Collection(
+ // Take(2) to ignore ComVisibleAttribute, SerializableAttribute, ... on int.
+ attributes.Attributes.Take(2),
+ attribute => Assert.IsType(attribute),
+ attribute => Assert.IsType(attribute));
+ Assert.Collection(
+ attributes.ParameterAttributes,
+ attribute => Assert.IsType(attribute),
+ attribute => Assert.IsType(attribute));
Assert.Null(attributes.PropertyAttributes);
+ Assert.Collection(
+ // Take(1) because the attribute or attributes after SerializableAttribute are framework-specific.
+ attributes.TypeAttributes.Take(1),
+ attribute => Assert.IsType(attribute));
+ }
+
+ [Fact]
+ public void GetAttributesForParameter_IncludesTypeAttributes()
+ {
+ // Arrange
+ var parameters = typeof(MethodWithParamAttributesType)
+ .GetMethod(nameof(MethodWithParamAttributesType.Method))
+ .GetParameters();
+
+ // Act
+ var attributes = ModelAttributes.GetAttributesForParameter(parameters[2]);
+
+ // Assert
+ Assert.Collection(attributes.Attributes,
+ attribute => Assert.IsType(attribute),
+ attribute => Assert.IsType(attribute));
+ Assert.IsType(Assert.Single(attributes.ParameterAttributes));
+ Assert.Null(attributes.PropertyAttributes);
+ Assert.IsType(Assert.Single(attributes.TypeAttributes));
}
[ClassValidator]
@@ -272,7 +302,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
private class ClassValidator : ValidationAttribute
{
- public override Boolean IsValid(Object value)
+ public override bool IsValid(object value)
{
return true;
}
@@ -305,7 +335,10 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
private class MethodWithParamAttributesType
{
[IrrelevantAttribute] // We verify this is ignored
- public void Method(object noAttribs, [Required, Range(1, 100)] int validationAttribs)
+ public void Method(
+ object noAttributes,
+ [Required, Range(1, 100)] int validationAttributes,
+ [BindRequired] BaseModel mergedAttributes)
{
}
}
@@ -314,4 +347,4 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
{
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/DataAnnotationsMetadataProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/DataAnnotationsMetadataProviderTest.cs
index 533fffd03c..ac90d1f155 100644
--- a/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/DataAnnotationsMetadataProviderTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/DataAnnotationsMetadataProviderTest.cs
@@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
stringLocalizerFactory: null);
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(new object[] { attribute }, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(new object[] { attribute }));
// Act
provider.CreateDisplayMetadata(context);
@@ -113,7 +113,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new[] { dataType, };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { dataType, displayFormat, };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -159,7 +159,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { editable };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new BindingMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new BindingMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateBindingMetadata(context);
@@ -180,7 +180,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { editable };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new BindingMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new BindingMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateBindingMetadata(context);
@@ -207,7 +207,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { display, displayName };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -234,7 +234,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { display, displayName };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -261,7 +261,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { display, displayName };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -298,7 +298,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { displayName };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -335,7 +335,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { display };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -367,7 +367,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { display };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -404,7 +404,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { display };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -441,7 +441,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { display };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -472,7 +472,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { display };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -509,7 +509,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { display };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -540,7 +540,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { display };
var key = ModelMetadataIdentity.ForType(typeof(string));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -588,7 +588,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { display };
var key = ModelMetadataIdentity.ForType(typeof(DataAnnotationsMetadataProviderTest));
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -635,7 +635,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var key = ModelMetadataIdentity.ForType(type);
var attributes = new object[0];
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -671,7 +671,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var key = ModelMetadataIdentity.ForType(type);
var attributes = new object[0];
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -805,7 +805,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var key = ModelMetadataIdentity.ForType(type);
var attributes = new object[0];
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -833,7 +833,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new object[0];
var key = ModelMetadataIdentity.ForType(type);
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
var stringLocalizer = new Mock(MockBehavior.Strict);
stringLocalizer
@@ -985,7 +985,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var key = ModelMetadataIdentity.ForType(type);
var attributes = new object[0];
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -1015,7 +1015,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var key = ModelMetadataIdentity.ForType(typeof(EnumWithDisplayOrder));
var attributes = new object[0];
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
// Act
provider.CreateDisplayMetadata(context);
@@ -1119,7 +1119,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { required };
var key = ModelMetadataIdentity.ForProperty(typeof(int), "Length", typeof(string));
- var context = new ValidationMetadataProviderContext(key, new ModelAttributes(new object[0], attributes, null));
+ var context = new ValidationMetadataProviderContext(key, GetModelAttributes(new object[0], attributes));
// Act
provider.CreateValidationMetadata(context);
@@ -1141,7 +1141,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { };
var key = ModelMetadataIdentity.ForProperty(typeof(int), "Length", typeof(string));
- var context = new ValidationMetadataProviderContext(key, new ModelAttributes(new object[0], attributes, null));
+ var context = new ValidationMetadataProviderContext(key, GetModelAttributes(new object[0], attributes));
context.ValidationMetadata.IsRequired = initialValue;
// Act
@@ -1164,7 +1164,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { new RequiredAttribute() };
var key = ModelMetadataIdentity.ForProperty(typeof(int), "Length", typeof(string));
- var context = new BindingMetadataProviderContext(key, new ModelAttributes(new object[0], attributes, null));
+ var context = new BindingMetadataProviderContext(key, GetModelAttributes(new object[0], attributes));
context.BindingMetadata.IsBindingRequired = initialValue;
// Act
@@ -1187,7 +1187,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attributes = new Attribute[] { };
var key = ModelMetadataIdentity.ForProperty(typeof(int), "Length", typeof(string));
- var context = new BindingMetadataProviderContext(key, new ModelAttributes(new object[0], attributes, null));
+ var context = new BindingMetadataProviderContext(key, GetModelAttributes(new object[0], attributes));
context.BindingMetadata.IsReadOnly = initialValue;
// Act
@@ -1208,7 +1208,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attribute = new TestValidationAttribute();
var attributes = new Attribute[] { attribute };
var key = ModelMetadataIdentity.ForProperty(typeof(int), "Length", typeof(string));
- var context = new ValidationMetadataProviderContext(key, new ModelAttributes(new object[0], attributes, null));
+ var context = new ValidationMetadataProviderContext(key, GetModelAttributes(new object[0], attributes));
// Act
provider.CreateValidationMetadata(context);
@@ -1229,7 +1229,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var attribute = new TestValidationAttribute();
var attributes = new Attribute[] { attribute };
var key = ModelMetadataIdentity.ForProperty(typeof(int), "Length", typeof(string));
- var context = new ValidationMetadataProviderContext(key, new ModelAttributes(new object[0], attributes, null));
+ var context = new ValidationMetadataProviderContext(key, GetModelAttributes(new object[0], attributes));
context.ValidationMetadata.ValidatorMetadata.Add(attribute);
// Act
@@ -1248,7 +1248,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
var key = ModelMetadataIdentity.ForType(typeof(EnumWithLocalizedDisplayNames));
var attributes = new object[0];
- var context = new DisplayMetadataProviderContext(key, new ModelAttributes(attributes, null, null));
+ var context = new DisplayMetadataProviderContext(key, GetModelAttributes(attributes));
provider.CreateDisplayMetadata(context);
return context.DisplayMetadata.EnumGroupedDisplayNamesAndValues;
@@ -1274,6 +1274,26 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
useStringLocalizer ? stringLocalizerFactory.Object : null);
}
+ private ModelAttributes GetModelAttributes(IEnumerable typeAttributes)
+ {
+#pragma warning disable CS0618 // Type or member is obsolete
+ var modelAttributes = new ModelAttributes(typeAttributes);
+#pragma warning restore CS0618 // Type or member is obsolete
+
+ return modelAttributes;
+ }
+
+ private ModelAttributes GetModelAttributes(
+ IEnumerable typeAttributes,
+ IEnumerable propertyAttributes)
+ {
+#pragma warning disable CS0618 // Type or member is obsolete
+ var modelAttributes = new ModelAttributes(propertyAttributes, typeAttributes);
+#pragma warning restore CS0618 // Type or member is obsolete
+
+ return modelAttributes;
+ }
+
private class KVPEnumGroupAndNameComparer : IEqualityComparer>
{
public static readonly IEqualityComparer> Instance = new KVPEnumGroupAndNameComparer();
diff --git a/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/DataMemberRequiredBindingMetadataProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/DataMemberRequiredBindingMetadataProviderTest.cs
index 48dc323474..499808aa94 100644
--- a/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/DataMemberRequiredBindingMetadataProviderTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/DataMemberRequiredBindingMetadataProviderTest.cs
@@ -1,6 +1,7 @@
// 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.Collections.Generic;
using System.Runtime.Serialization;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
@@ -25,7 +26,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
typeof(string),
nameof(ClassWithDataMemberIsRequiredTrue.StringProperty),
typeof(ClassWithDataMemberIsRequiredTrue));
- var context = new BindingMetadataProviderContext(key, new ModelAttributes(new object[0], attributes, null));
+ var context = new BindingMetadataProviderContext(key, GetModelAttributes(new object[0], attributes));
// Act
provider.CreateBindingMetadata(context);
@@ -51,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
typeof(string),
nameof(ClassWithDataMemberIsRequiredFalse.StringProperty),
typeof(ClassWithDataMemberIsRequiredFalse));
- var context = new BindingMetadataProviderContext(key, new ModelAttributes(new object[0], attributes, null));
+ var context = new BindingMetadataProviderContext(key, GetModelAttributes(new object[0], attributes));
context.BindingMetadata.IsBindingRequired = initialValue;
@@ -76,7 +77,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
};
var key = ModelMetadataIdentity.ForType(typeof(ClassWithDataMemberIsRequiredTrue));
- var context = new BindingMetadataProviderContext(key, new ModelAttributes(new object[0], attributes, null));
+ var context = new BindingMetadataProviderContext(key, GetModelAttributes(new object[0], attributes));
context.BindingMetadata.IsBindingRequired = initialValue;
@@ -99,7 +100,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
typeof(string),
nameof(ClassWithoutAttributes.StringProperty),
typeof(ClassWithoutAttributes));
- var context = new BindingMetadataProviderContext(key, new ModelAttributes(new object[0], new object[0], null));
+ var context = new BindingMetadataProviderContext(key, GetModelAttributes(new object[0], new object[0]));
context.BindingMetadata.IsBindingRequired = initialValue;
@@ -127,7 +128,7 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
typeof(string),
nameof(ClassWithDataMemberIsRequiredTrueWithoutDataContract.StringProperty),
typeof(ClassWithDataMemberIsRequiredTrueWithoutDataContract));
- var context = new BindingMetadataProviderContext(key, new ModelAttributes(new object[0], attributes, null));
+ var context = new BindingMetadataProviderContext(key, GetModelAttributes(new object[0], attributes));
context.BindingMetadata.IsBindingRequired = initialValue;
@@ -138,6 +139,17 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
Assert.Equal(initialValue, context.BindingMetadata.IsBindingRequired);
}
+ private ModelAttributes GetModelAttributes(
+ IEnumerable typeAttributes,
+ IEnumerable propertyAttributes)
+ {
+#pragma warning disable CS0618 // Type or member is obsolete
+ var modelAttributes = new ModelAttributes(propertyAttributes, typeAttributes);
+#pragma warning restore CS0618 // Type or member is obsolete
+
+ return modelAttributes;
+ }
+
[DataContract]
private class ClassWithDataMemberIsRequiredTrue
{
diff --git a/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/ModelMetadataProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/ModelMetadataProviderTest.cs
index 62602e8c3e..4002e30c99 100644
--- a/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/ModelMetadataProviderTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.DataAnnotations.Test/Internal/ModelMetadataProviderTest.cs
@@ -1067,7 +1067,9 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
{
return new DefaultMetadataDetails(
key,
- new ModelAttributes(_attributes.Concat(entry.ModelAttributes.TypeAttributes).ToArray(), null, null));
+#pragma warning disable CS0618 // Type or member is obsolete
+ new ModelAttributes(_attributes.Concat(entry.ModelAttributes.TypeAttributes).ToArray()));
+#pragma warning restore CS0618 // Type or member is obsolete
}
return entry;
@@ -1080,10 +1082,14 @@ namespace Microsoft.AspNetCore.Mvc.DataAnnotations.Internal
{
return new DefaultMetadataDetails(
e.Key,
- new ModelAttributes(e.ModelAttributes.TypeAttributes, _attributes.Concat(e.ModelAttributes.PropertyAttributes), null));
+#pragma warning disable CS0618 // Type or member is obsolete
+ new ModelAttributes(
+ _attributes.Concat(e.ModelAttributes.PropertyAttributes),
+ e.ModelAttributes.TypeAttributes));
+#pragma warning restore CS0618 // Type or member is obsolete
})
.ToArray();
}
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ActionParametersIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ActionParametersIntegrationTest.cs
index 4e349de9b9..fcd5923101 100644
--- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ActionParametersIntegrationTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ActionParametersIntegrationTest.cs
@@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
@@ -469,14 +468,17 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
public async Task ActionParameter_CustomModelBinder_CanCreateModels_ForParameterlessConstructorTypes()
{
// Arrange
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(binderProvider: new CustomComplexTypeModelBinderProvider());
- var parameter = new ParameterDescriptor()
+ var testContext = ModelBindingTestHelper.GetTestContext();
+ var modelState = testContext.ModelState;
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(
+ testContext.MvcOptions,
+ new CustomComplexTypeModelBinderProvider());
+
+ var parameter = new ParameterDescriptor
{
Name = "prefix",
ParameterType = typeof(ClassWithNoDefaultConstructor)
};
- var testContext = ModelBindingTestHelper.GetTestContext();
- var modelState = testContext.ModelState;
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -850,7 +852,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
public IEnumerator GetEnumerator()
{
- foreach (T t in _original)
+ foreach (var t in _original)
{
yield return t;
}
@@ -891,4 +893,4 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
}
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BinderTypeBasedModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BinderTypeBasedModelBinderIntegrationTest.cs
index 688cbbffef..b35b180597 100644
--- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BinderTypeBasedModelBinderIntegrationTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BinderTypeBasedModelBinderIntegrationTest.cs
@@ -5,6 +5,7 @@ using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Abstractions;
+using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Testing;
using Xunit;
@@ -148,13 +149,63 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
// type. This should behave identically to such an attribute on an action parameter. (Tests such as
// BindParameter_WithData_WithPrefix_GetsBound cover associating [ModelBinder] with an action parameter.)
//
- // This is a regression test for aspnet/Mvc#4652
+ // This is a regression test for aspnet/Mvc#4652 and aspnet/Mvc#7595
[Theory]
[MemberData(nameof(NullAndEmptyBindingInfo))]
public async Task BinderTypeOnParameterType_WithData_EmptyPrefix_GetsBound(BindingInfo bindingInfo)
{
// Arrange
var parameterBinder = ModelBindingTestHelper.GetParameterBinder();
+ var parameters = typeof(TestController).GetMethod(nameof(TestController.Action)).GetParameters();
+ var parameter = new ControllerParameterDescriptor
+ {
+ Name = "Parameter1",
+ BindingInfo = bindingInfo,
+ ParameterInfo = parameters[0],
+ ParameterType = typeof(Address),
+ };
+
+ var testContext = ModelBindingTestHelper.GetTestContext();
+ var modelState = testContext.ModelState;
+
+ // Act
+ var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
+
+ // Assert
+ // ModelBindingResult
+ Assert.True(modelBindingResult.IsModelSet);
+
+ // Model
+ var address = Assert.IsType(modelBindingResult.Model);
+ Assert.Equal("SomeStreet", address.Street);
+
+ // ModelState
+ Assert.True(modelState.IsValid);
+ var kvp = Assert.Single(modelState);
+ Assert.Equal("Street", kvp.Key);
+ var entry = kvp.Value;
+ Assert.NotNull(entry);
+ Assert.Equal(ModelValidationState.Valid, entry.ValidationState);
+ Assert.NotNull(entry.RawValue); // Value is set by test model binder, no need to validate it.
+ }
+
+ // Make sure the metadata is honored when a [ModelBinder] attribute is associated with an action parameter's
+ // type. This should behave identically to such an attribute on an action parameter. (Tests such as
+ // BindParameter_WithData_WithPrefix_GetsBound cover associating [ModelBinder] with an action parameter.)
+ //
+ // This is a regression test for aspnet/Mvc#4652
+ [Theory]
+ [MemberData(nameof(NullAndEmptyBindingInfo))]
+ public async Task BinderTypeOnParameterType_WithDataEmptyPrefixAndVersion20_GetsBound(
+ BindingInfo bindingInfo)
+ {
+ // Arrange
+ var testContext = ModelBindingTestHelper.GetTestContext(
+ // ParameterBinder will use ModelMetadata for typeof(Address), not Parameter1's ParameterInfo.
+ updateOptions: options => options.AllowValidatingTopLevelNodes = false);
+
+ var modelState = testContext.ModelState;
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
var parameter = new ParameterDescriptor
{
Name = "Parameter1",
@@ -162,9 +213,6 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
ParameterType = typeof(Address),
};
- var testContext = ModelBindingTestHelper.GetTestContext();
- var modelState = testContext.ModelState;
-
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -419,5 +467,12 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
return Task.CompletedTask;
}
}
+
+ private class TestController
+ {
+ public void Action(Address address)
+ {
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BodyValidationIntegrationTests.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BodyValidationIntegrationTests.cs
index 2257eb6eb1..e4ee6a548c 100644
--- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BodyValidationIntegrationTests.cs
+++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/BodyValidationIntegrationTests.cs
@@ -377,15 +377,11 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
request.Body = new MemoryStream(Encoding.UTF8.GetBytes(string.Empty));
request.ContentType = "application/json";
});
+ testContext.MvcOptions.AllowEmptyInputInBodyModelBinding = true;
var modelState = testContext.ModelState;
-
var addressRequired = ValidationAttributeUtil.GetRequiredErrorMessage("Address");
-
- var optionsAccessor = testContext.GetService>();
- optionsAccessor.Value.AllowEmptyInputInBodyModelBinding = true;
-
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(optionsAccessor.Value);
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -422,14 +418,10 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
request.Body = new MemoryStream(Encoding.UTF8.GetBytes(string.Empty));
request.ContentType = "application/json";
});
+ testContext.MvcOptions.AllowEmptyInputInBodyModelBinding = true;
- var httpContext = testContext.HttpContext;
var modelState = testContext.ModelState;
-
- var optionsAccessor = testContext.GetService>();
- optionsAccessor.Value.AllowEmptyInputInBodyModelBinding = true;
-
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(optionsAccessor.Value);
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -626,10 +618,8 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
},
options => options.AllowEmptyInputInBodyModelBinding = allowEmptyInputInBodyModelBindingSetting);
- var optionsAccessor = testContext.GetService>();
var modelState = testContext.ModelState;
-
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(optionsAccessor.Value);
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -793,7 +783,16 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
.ForProperty(nameof(Person6.Address))
.BindingDetails(binding => binding.BindingSource = BindingSource.Body);
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(metadataProvider);
+ var testContext = ModelBindingTestHelper.GetTestContext(
+ request =>
+ {
+ request.Body = new MemoryStream(Encoding.UTF8.GetBytes(inputText));
+ request.ContentType = "application/json";
+ },
+ metadataProvider: metadataProvider);
+
+ var modelState = testContext.ModelState;
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
var parameter = new ParameterDescriptor
{
Name = "parameter-name",
@@ -801,15 +800,6 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
ParameterType = typeof(Person6),
};
- var testContext = ModelBindingTestHelper.GetTestContext(
- request =>
- {
- request.Body = new MemoryStream(Encoding.UTF8.GetBytes(inputText));
- request.ContentType = "application/json";
- });
- testContext.MetadataProvider = metadataProvider;
- var modelState = testContext.ModelState;
-
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -839,7 +829,16 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
.ForType()
.BindingDetails(binding => binding.BindingSource = BindingSource.Body);
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(metadataProvider);
+ var testContext = ModelBindingTestHelper.GetTestContext(
+ request =>
+ {
+ request.Body = new MemoryStream(Encoding.UTF8.GetBytes(inputText));
+ request.ContentType = "application/json";
+ },
+ metadataProvider: metadataProvider);
+
+ var modelState = testContext.ModelState;
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
var parameter = new ParameterDescriptor
{
Name = "parameter-name",
@@ -847,15 +846,6 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
ParameterType = typeof(Address6),
};
- var testContext = ModelBindingTestHelper.GetTestContext(
- request =>
- {
- request.Body = new MemoryStream(Encoding.UTF8.GetBytes(inputText));
- request.ContentType = "application/json";
- });
- testContext.MetadataProvider = metadataProvider;
- var modelState = testContext.ModelState;
-
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -890,4 +880,4 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
return result;
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ComplexTypeModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ComplexTypeModelBinderIntegrationTest.cs
index 5a017bd1d0..e3f693f58a 100644
--- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ComplexTypeModelBinderIntegrationTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ComplexTypeModelBinderIntegrationTest.cs
@@ -11,7 +11,6 @@ using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Testing;
-using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using Xunit;
@@ -148,13 +147,11 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
request.ContentType = "application/json";
});
- var optionsAccessor = testContext.GetService>();
- optionsAccessor.Value.AllowEmptyInputInBodyModelBinding = true;
+ testContext.MvcOptions.AllowEmptyInputInBodyModelBinding = true;
var modelState = testContext.ModelState;
var valueProvider = await CompositeValueProvider.CreateAsync(testContext);
-
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(optionsAccessor.Value);
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(testContext, valueProvider, parameter);
@@ -1607,7 +1604,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var model = Assert.IsType(modelBindingResult.Model);
Assert.Equal("bill", model.Name);
- Assert.Equal(default(KeyValuePair), model.ProductId);
+ Assert.Equal(default, model.ProductId);
Assert.Single(modelState);
Assert.Equal(0, modelState.ErrorCount);
@@ -1646,7 +1643,7 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
var model = Assert.IsType(modelBindingResult.Model);
Assert.Null(model.Name);
- Assert.Equal(default(KeyValuePair), model.ProductId);
+ Assert.Equal(default, model.ProductId);
Assert.Empty(modelState);
Assert.Equal(0, modelState.ErrorCount);
@@ -2728,4 +2725,4 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
});
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ExcludeBindingMetadataProviderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ExcludeBindingMetadataProviderIntegrationTest.cs
index 8617f8551c..185f828a86 100644
--- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ExcludeBindingMetadataProviderIntegrationTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ExcludeBindingMetadataProviderIntegrationTest.cs
@@ -67,12 +67,12 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
{
// Arrange
var options = new MvcOptions();
- var setup = new MvcCoreMvcOptionsSetup(new TestHttpRequestStreamReaderFactory());
var modelBinderProvider = new TypeModelBinderProvider();
// Adding a custom model binder for Type to ensure it doesn't get called
options.ModelBinderProviders.Insert(0, modelBinderProvider);
+ var setup = new MvcCoreMvcOptionsSetup(new TestHttpRequestStreamReaderFactory());
setup.Configure(options);
// Remove the ExcludeBindingMetadataProvider
@@ -84,7 +84,20 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
}
}
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(options);
+ var metadataProvider = TestModelMetadataProvider.CreateProvider(options.ModelMetadataDetailsProviders);
+ var testContext = ModelBindingTestHelper.GetTestContext(
+ request =>
+ {
+ request.Form = new FormCollection(new Dictionary
+ {
+ { "name", new[] { "Fred" } },
+ { "type", new[] { "SomeType" } },
+ });
+ },
+ metadataProvider: metadataProvider,
+ mvcOptions: options);
+
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
var parameter = new ParameterDescriptor()
{
Name = "Parameter1",
@@ -92,15 +105,6 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
ParameterType = typeof(TypesBundle),
};
- var testContext = ModelBindingTestHelper.GetTestContext(request =>
- {
- request.Form = new FormCollection(new Dictionary
- {
- { "name", new[] { "Fred" } },
- { "type", new[] { "SomeType" } },
- });
- });
-
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -145,4 +149,4 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
}
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/GenericModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/GenericModelBinderIntegrationTest.cs
index acb91f6ed5..22a7be2d24 100644
--- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/GenericModelBinderIntegrationTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/GenericModelBinderIntegrationTest.cs
@@ -196,18 +196,20 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
public async Task GenericModelBinder_BindsCollection_ElementTypeUsesGreedyModelBinder_WithPrefix_Success()
{
// Arrange
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(binderProvider: new AddressBinderProvider());
- var parameter = new ParameterDescriptor()
- {
- Name = "parameter",
- ParameterType = typeof(Address[])
- };
-
// Need to have a key here so that the GenericModelBinder will recurse to bind elements.
var testContext = ModelBindingTestHelper.GetTestContext(
request => request.QueryString = new QueryString("?parameter.index=0"));
var modelState = testContext.ModelState;
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(
+ testContext.MvcOptions,
+ new AddressBinderProvider());
+
+ var parameter = new ParameterDescriptor()
+ {
+ Name = "parameter",
+ ParameterType = typeof(Address[])
+ };
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -638,4 +640,4 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/KeyValuePairModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/KeyValuePairModelBinderIntegrationTest.cs
index 79c0803f15..42b6b827f9 100644
--- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/KeyValuePairModelBinderIntegrationTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/KeyValuePairModelBinderIntegrationTest.cs
@@ -104,17 +104,20 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
() => $"Hurts when nothing is provided.");
}));
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(metadataProvider);
+ var testContext = ModelBindingTestHelper.GetTestContext(
+ request =>
+ {
+ request.QueryString = new QueryString("?parameter.Value=10");
+ },
+ metadataProvider: metadataProvider);
+
+ var modelState = testContext.ModelState;
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
var parameter = new ParameterDescriptor
{
Name = "parameter",
ParameterType = typeof(KeyValuePair)
};
- var testContext = ModelBindingTestHelper.GetTestContext(request =>
- {
- request.QueryString = new QueryString("?parameter.Value=10");
- });
- var modelState = testContext.ModelState;
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -188,18 +191,20 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
() => $"Hurts when nothing is provided.");
}));
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(metadataProvider);
+ var testContext = ModelBindingTestHelper.GetTestContext(
+ request =>
+ {
+ request.QueryString = new QueryString("?parameter.Key=10");
+ },
+ metadataProvider: metadataProvider);
+ var modelState = testContext.ModelState;
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
var parameter = new ParameterDescriptor
{
Name = "parameter",
ParameterType = typeof(KeyValuePair)
};
- var testContext = ModelBindingTestHelper.GetTestContext(request =>
- {
- request.QueryString = new QueryString("?parameter.Key=10");
- });
- var modelState = testContext.ModelState;
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -544,4 +549,4 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
Assert.Equal("value2", entry.RawValue);
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ModelBindingTestContext.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ModelBindingTestContext.cs
index 2457a8ca1e..4cf87f2300 100644
--- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ModelBindingTestContext.cs
+++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ModelBindingTestContext.cs
@@ -9,6 +9,8 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
{
public IModelMetadataProvider MetadataProvider { get; set; }
+ public MvcOptions MvcOptions { get; set; }
+
public T GetService()
{
return (T)HttpContext.RequestServices.GetService(typeof(T));
diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ModelBindingTestHelper.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ModelBindingTestHelper.cs
index 00d2d6046d..6aa9da7cf0 100644
--- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ModelBindingTestHelper.cs
+++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ModelBindingTestHelper.cs
@@ -26,17 +26,21 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
public static ModelBindingTestContext GetTestContext(
Action updateRequest = null,
Action updateOptions = null,
- ControllerActionDescriptor actionDescriptor = null)
+ ControllerActionDescriptor actionDescriptor = null,
+ IModelMetadataProvider metadataProvider = null,
+ MvcOptions mvcOptions = null)
{
- var httpContext = GetHttpContext(updateRequest, updateOptions);
+ var httpContext = GetHttpContext(metadataProvider, updateRequest, updateOptions, mvcOptions);
var services = httpContext.RequestServices;
+ metadataProvider = metadataProvider ?? services.GetRequiredService();
var options = services.GetRequiredService>();
- var context = new ModelBindingTestContext()
+ var context = new ModelBindingTestContext
{
ActionDescriptor = actionDescriptor ?? new ControllerActionDescriptor(),
HttpContext = httpContext,
- MetadataProvider = TestModelMetadataProvider.CreateDefaultProvider(),
+ MetadataProvider = metadataProvider,
+ MvcOptions = options.Value,
RouteData = new RouteData(),
ValueProviderFactories = new List(options.Value.ValueProviderFactories),
};
@@ -80,10 +84,8 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
IModelBinderProvider binderProvider = null,
MvcOptions mvcOptions = null)
{
- var services = GetServices();
- var options = mvcOptions != null
- ? Options.Create(mvcOptions)
- : services.GetRequiredService>();
+ var services = GetServices(metadataProvider, mvcOptions: mvcOptions);
+ var options = services.GetRequiredService>();
if (binderProvider != null)
{
@@ -102,15 +104,15 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
public static IModelBinderFactory GetModelBinderFactory(
IModelMetadataProvider metadataProvider,
- IOptions options = null)
+ IServiceProvider services = null)
{
- var services = GetServices();
-
- if (options == null)
+ if (services == null)
{
- options = services.GetRequiredService>();
+ services = GetServices(metadataProvider);
}
+ var options = services.GetRequiredService>();
+
return new ModelBinderFactory(metadataProvider, options, services);
}
@@ -136,23 +138,52 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
}
private static HttpContext GetHttpContext(
+ IModelMetadataProvider metadataProvider,
Action updateRequest = null,
- Action updateOptions = null)
+ Action updateOptions = null,
+ MvcOptions mvcOptions = null)
{
var httpContext = new DefaultHttpContext();
httpContext.Features.Set(new CancellableRequestLifetimeFeature());
updateRequest?.Invoke(httpContext.Request);
- httpContext.RequestServices = GetServices(updateOptions);
+ httpContext.RequestServices = GetServices(metadataProvider, updateOptions, mvcOptions);
return httpContext;
}
- public static IServiceProvider GetServices(Action updateOptions = null)
+ public static IServiceProvider GetServices(
+ IModelMetadataProvider metadataProvider,
+ Action updateOptions = null,
+ MvcOptions mvcOptions = null)
{
var serviceCollection = new ServiceCollection();
- serviceCollection.AddAuthorization();
serviceCollection.AddSingleton(new ApplicationPartManager());
+ if (metadataProvider != null)
+ {
+ serviceCollection.AddSingleton(metadataProvider);
+ }
+ else if (updateOptions != null || mvcOptions != null)
+ {
+ serviceCollection.AddSingleton(services =>
+ {
+ var optionsAccessor = services.GetRequiredService>();
+ return TestModelMetadataProvider.CreateProvider(optionsAccessor.Value.ModelMetadataDetailsProviders);
+ });
+ }
+ else
+ {
+ serviceCollection.AddSingleton(services =>
+ {
+ return TestModelMetadataProvider.CreateDefaultProvider();
+ });
+ }
+
+ if (mvcOptions != null)
+ {
+ serviceCollection.AddSingleton(Options.Create(mvcOptions));
+ }
+
serviceCollection
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ParameterBinderExtensions.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ParameterBinderExtensions.cs
index 8d839c83a3..2cf116e039 100644
--- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ParameterBinderExtensions.cs
+++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ParameterBinderExtensions.cs
@@ -1,23 +1,60 @@
// 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.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Abstractions;
+using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.ModelBinding;
+using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
+using Xunit;
namespace Microsoft.AspNetCore.Mvc.IntegrationTests
{
public static class ParameterBinderExtensions
{
- public static async Task BindModelAsync(
+ public static Task BindModelAsync(
this ParameterBinder parameterBinder,
- ParameterDescriptor parameter,
+ ParameterDescriptor parameter,
ControllerContext context)
{
- var valueProvider = await CompositeValueProvider.CreateAsync(context);
-
- return await parameterBinder.BindModelAsync(context, valueProvider, parameter);
+ var optionsAccessor = context.HttpContext.RequestServices.GetService>();
+ Assert.NotNull(optionsAccessor?.Value); // Guard
+ var modelMetadataProvider = context.HttpContext.RequestServices.GetService();
+ Assert.NotNull(modelMetadataProvider); // Guard
+
+ // Imitate a bit of ControllerBinderDelegateProvider and PageBinderFactory
+ ParameterInfo parameterInfo;
+ if (parameter is ControllerParameterDescriptor controllerParameterDescriptor)
+ {
+ parameterInfo = controllerParameterDescriptor.ParameterInfo;
+ }
+ else if (parameter is HandlerParameterDescriptor handlerParameterDescriptor)
+ {
+ parameterInfo = handlerParameterDescriptor.ParameterInfo;
+ }
+ else
+ {
+ parameterInfo = null;
+ }
+
+ ModelMetadata metadata;
+ if (optionsAccessor.Value.AllowValidatingTopLevelNodes &&
+ modelMetadataProvider is ModelMetadataProvider modelMetadataProviderBase &&
+ parameterInfo != null)
+ {
+ metadata = modelMetadataProviderBase.GetMetadataForParameter(parameterInfo);
+ }
+ else
+ {
+ metadata = modelMetadataProvider.GetMetadataForType(parameter.ParameterType);
+ }
+
+ return parameterBinder.BindModelAsync(parameter, context, modelMetadataProvider, metadata);
}
+
public static async Task BindModelAsync(
this ParameterBinder parameterBinder,
ParameterDescriptor parameter,
@@ -26,8 +63,9 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
ModelMetadata modelMetadata)
{
var valueProvider = await CompositeValueProvider.CreateAsync(context);
-
- var modelBinderFactory = ModelBindingTestHelper.GetModelBinderFactory(modelMetadataProvider);
+ var modelBinderFactory = ModelBindingTestHelper.GetModelBinderFactory(
+ modelMetadataProvider,
+ context.HttpContext.RequestServices);
var modelBinder = modelBinderFactory.CreateBinder(new ModelBinderFactoryContext
{
diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ServicesModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ServicesModelBinderIntegrationTest.cs
index 8d3f83f68f..1ea4cbf95b 100644
--- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ServicesModelBinderIntegrationTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ServicesModelBinderIntegrationTest.cs
@@ -205,7 +205,9 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
.ForProperty(nameof(Person.Service))
.BindingDetails(binding => binding.BindingSource = BindingSource.Services);
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(metadataProvider);
+ var testContext = ModelBindingTestHelper.GetTestContext(metadataProvider: metadataProvider);
+ var modelState = testContext.ModelState;
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
var parameter = new ParameterDescriptor
{
Name = "parameter-name",
@@ -213,10 +215,6 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
ParameterType = typeof(Person),
};
- var testContext = ModelBindingTestHelper.GetTestContext();
- testContext.MetadataProvider = metadataProvider;
- var modelState = testContext.ModelState;
-
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -245,7 +243,9 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
.ForType()
.BindingDetails(binding => binding.BindingSource = BindingSource.Services);
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(metadataProvider);
+ var testContext = ModelBindingTestHelper.GetTestContext(metadataProvider: metadataProvider);
+ var modelState = testContext.ModelState;
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
var parameter = new ParameterDescriptor
{
Name = "parameter-name",
@@ -253,10 +253,6 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
ParameterType = typeof(JsonOutputFormatter),
};
- var testContext = ModelBindingTestHelper.GetTestContext();
- testContext.MetadataProvider = metadataProvider;
- var modelState = testContext.ModelState;
-
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -268,4 +264,4 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
Assert.Empty(modelState);
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/SimpleTypeModelBinderIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/SimpleTypeModelBinderIntegrationTest.cs
index 0d5cede662..420939c66b 100644
--- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/SimpleTypeModelBinderIntegrationTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/SimpleTypeModelBinderIntegrationTest.cs
@@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
-using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@@ -304,7 +303,16 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
binding.ModelBindingMessageProvider.SetNonPropertyAttemptedValueIsInvalidAccessor(
(value) => $"Hmm, '{ value }' is not a valid value.");
});
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(metadataProvider);
+
+ var testContext = ModelBindingTestHelper.GetTestContext(
+ request =>
+ {
+ request.QueryString = QueryString.Create("Parameter1", "abcd");
+ },
+ metadataProvider: metadataProvider);
+
+ var modelState = testContext.ModelState;
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
var parameter = new ParameterDescriptor()
{
Name = "Parameter1",
@@ -312,13 +320,6 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
ParameterType = parameterType
};
- var testContext = ModelBindingTestHelper.GetTestContext(request =>
- {
- request.QueryString = QueryString.Create("Parameter1", "abcd");
- });
-
- var modelState = testContext.ModelState;
-
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
@@ -405,8 +406,16 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
binding.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(
value => $"Hurts when '{ value }' is provided.");
});
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(metadataProvider);
+ var testContext = ModelBindingTestHelper.GetTestContext(
+ request =>
+ {
+ request.QueryString = QueryString.Create("Parameter1", string.Empty);
+ },
+ metadataProvider: metadataProvider);
+
+ var modelState = testContext.ModelState;
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
var parameter = new ParameterDescriptor
{
Name = "Parameter1",
@@ -414,11 +423,6 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
ParameterType = parameterType
};
- var testContext = ModelBindingTestHelper.GetTestContext(request =>
- {
- request.QueryString = QueryString.Create("Parameter1", string.Empty);
- });
- var modelState = testContext.ModelState;
// Act
var modelBindingResult = await parameterBinder.BindModelAsync(parameter, testContext);
diff --git a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ValidationIntegrationTests.cs b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ValidationIntegrationTests.cs
index 036f758433..e5df3d1233 100644
--- a/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ValidationIntegrationTests.cs
+++ b/test/Microsoft.AspNetCore.Mvc.IntegrationTests/ValidationIntegrationTests.cs
@@ -1608,7 +1608,6 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
ParameterType = typeof(Order11)
};
- MvcOptions testOptions = null;
var input = "{\"Zip\":\"47\"}";
var testContext = ModelBindingTestHelper.GetTestContext(
request =>
@@ -1621,10 +1620,9 @@ namespace Microsoft.AspNetCore.Mvc.IntegrationTests
options =>
{
options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(Address)));
- testOptions = options;
});
- var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testOptions);
+ var parameterBinder = ModelBindingTestHelper.GetParameterBinder(testContext.HttpContext.RequestServices);
var modelState = testContext.ModelState;
// Act
diff --git a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/FormatWeekHelperTest.cs b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/FormatWeekHelperTest.cs
index 9586bf664e..97f45f0c0f 100644
--- a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/FormatWeekHelperTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/FormatWeekHelperTest.cs
@@ -26,7 +26,9 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal
var detailsProvider = new DefaultCompositeMetadataDetailsProvider(
Enumerable.Empty());
var key = ModelMetadataIdentity.ForType(typeof(DateTime));
- var cache = new DefaultMetadataDetails(key, new ModelAttributes(new object[0], null, null));
+#pragma warning disable CS0618 // Type or member is obsolete
+ var cache = new DefaultMetadataDetails(key, new ModelAttributes(new object[0]));
+#pragma warning restore CS0618 // Type or member is obsolete
var provider = new EmptyModelMetadataProvider();
var metadata = new DefaultModelMetadata(provider, detailsProvider, cache);