diff --git a/src/Mvc/Mvc.Abstractions/ref/Microsoft.AspNetCore.Mvc.Abstractions.netcoreapp.cs b/src/Mvc/Mvc.Abstractions/ref/Microsoft.AspNetCore.Mvc.Abstractions.netcoreapp.cs
index a13240eca5..e41015f9e9 100644
--- a/src/Mvc/Mvc.Abstractions/ref/Microsoft.AspNetCore.Mvc.Abstractions.netcoreapp.cs
+++ b/src/Mvc/Mvc.Abstractions/ref/Microsoft.AspNetCore.Mvc.Abstractions.netcoreapp.cs
@@ -883,10 +883,13 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
public System.Type ModelType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
public System.Reflection.ParameterInfo ParameterInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
+ public System.Reflection.PropertyInfo PropertyInfo { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
public bool Equals(Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity other) { throw null; }
public override bool Equals(object obj) { throw null; }
public static Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity ForParameter(System.Reflection.ParameterInfo parameter) { throw null; }
public static Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity ForParameter(System.Reflection.ParameterInfo parameter, System.Type modelType) { throw null; }
+ public static Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity ForProperty(System.Reflection.PropertyInfo propertyInfo, System.Type modelType, System.Type containerType) { throw null; }
+ [System.ObsoleteAttribute("This API is obsolete and may be removed in a future release.")]
public static Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity ForProperty(System.Type modelType, string name, System.Type containerType) { throw null; }
public static Microsoft.AspNetCore.Mvc.ModelBinding.Metadata.ModelMetadataIdentity ForType(System.Type modelType) { throw null; }
public override int GetHashCode() { throw null; }
diff --git a/src/Mvc/Mvc.Abstractions/src/ModelBinding/Metadata/ModelMetadataIdentity.cs b/src/Mvc/Mvc.Abstractions/src/ModelBinding/Metadata/ModelMetadataIdentity.cs
index 655bd9cb74..9f183c1cb2 100644
--- a/src/Mvc/Mvc.Abstractions/src/ModelBinding/Metadata/ModelMetadataIdentity.cs
+++ b/src/Mvc/Mvc.Abstractions/src/ModelBinding/Metadata/ModelMetadataIdentity.cs
@@ -17,12 +17,14 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
Type modelType,
string name = null,
Type containerType = null,
- ParameterInfo parameterInfo = null)
+ ParameterInfo parameterInfo = null,
+ PropertyInfo propertyInfo = null)
{
ModelType = modelType;
Name = name;
ContainerType = containerType;
ParameterInfo = parameterInfo;
+ PropertyInfo = propertyInfo;
}
///
@@ -47,6 +49,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
/// The name of the property.
/// The container type of the model property.
/// A .
+ [Obsolete("This API is obsolete and may be removed in a future release.")]
public static ModelMetadataIdentity ForProperty(
Type modelType,
string name,
@@ -70,6 +73,36 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
return new ModelMetadataIdentity(modelType, name, containerType);
}
+ ///
+ /// Creates a for the provided property.
+ ///
+ /// The model type.
+ /// The property.
+ /// The container type of the model property.
+ /// A .
+ public static ModelMetadataIdentity ForProperty(
+ PropertyInfo propertyInfo,
+ Type modelType,
+ Type containerType)
+ {
+ if (propertyInfo == null)
+ {
+ throw new ArgumentNullException(nameof(propertyInfo));
+ }
+
+ if (modelType == null)
+ {
+ throw new ArgumentNullException(nameof(modelType));
+ }
+
+ if (containerType == null)
+ {
+ throw new ArgumentNullException(nameof(containerType));
+ }
+
+ return new ModelMetadataIdentity(modelType, propertyInfo.Name, containerType, propertyInfo: propertyInfo);
+ }
+
///
/// Creates a for the provided parameter.
///
@@ -145,6 +178,12 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
///
public ParameterInfo ParameterInfo { get; }
+ ///
+ /// Gets a descriptor for the property, or null if this instance
+ /// does not represent a property.
+ ///
+ public PropertyInfo PropertyInfo { get; }
+
///
public bool Equals(ModelMetadataIdentity other)
{
@@ -152,7 +191,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
ContainerType == other.ContainerType &&
ModelType == other.ModelType &&
Name == other.Name &&
- ParameterInfo == other.ParameterInfo;
+ ParameterInfo == other.ParameterInfo &&
+ PropertyInfo == other.PropertyInfo;
}
///
@@ -170,6 +210,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
hash.Add(ModelType);
hash.Add(Name, StringComparer.Ordinal);
hash.Add(ParameterInfo);
+ hash.Add(PropertyInfo);
return hash;
}
}
diff --git a/src/Mvc/Mvc.Abstractions/test/ModelBinding/ModelMetadataTest.cs b/src/Mvc/Mvc.Abstractions/test/ModelBinding/ModelMetadataTest.cs
index e72dea57e4..2f71dffe32 100644
--- a/src/Mvc/Mvc.Abstractions/test/ModelBinding/ModelMetadataTest.cs
+++ b/src/Mvc/Mvc.Abstractions/test/ModelBinding/ModelMetadataTest.cs
@@ -270,7 +270,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public void ContainerType_ReturnExpectedMetadata_ForProperty()
{
// Arrange & Act
- var metadata = new TestModelMetadata(typeof(int), nameof(string.Length), typeof(string));
+ var property = typeof(string).GetProperty(nameof(string.Length));
+ var metadata = new TestModelMetadata(property, typeof(int), typeof(string));
// Assert
Assert.Equal(typeof(string), metadata.ContainerType);
@@ -308,7 +309,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public void Names_ReturnExpectedMetadata_ForProperty()
{
// Arrange & Act
- var metadata = new TestModelMetadata(typeof(int), nameof(string.Length), typeof(string));
+ var property = typeof(string).GetProperty(nameof(string.Length));
+ var metadata = new TestModelMetadata(property, typeof(int), typeof(string));
// Assert
Assert.Equal(nameof(string.Length), metadata.Name);
@@ -322,7 +324,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public void GetDisplayName_ReturnsDisplayName_IfSet()
{
// Arrange
- var metadata = new TestModelMetadata(typeof(int), "Length", typeof(string));
+ var property = typeof(string).GetProperty(nameof(string.Length));
+ var metadata = new TestModelMetadata(property, typeof(int), typeof(string));
metadata.SetDisplayName("displayName");
// Act
@@ -351,7 +354,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
public void GetDisplayName_ReturnsPropertyName_WhenSetAndDisplayNameIsNull()
{
// Arrange
- var metadata = new TestModelMetadata(typeof(int), "Length", typeof(string));
+ var property = typeof(string).GetProperty(nameof(string.Length));
+ var metadata = new TestModelMetadata(property, typeof(int), typeof(string));
// Act
var result = metadata.GetDisplayName();
@@ -419,8 +423,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
{
}
- public TestModelMetadata(Type modelType, string propertyName, Type containerType)
- : base(ModelMetadataIdentity.ForProperty(modelType, propertyName, containerType))
+ public TestModelMetadata(PropertyInfo propertyInfo, Type modelType, Type containerType)
+ : base(ModelMetadataIdentity.ForProperty(propertyInfo, modelType, containerType))
{
}
diff --git a/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/DefaultModelMetadataProvider.cs b/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/DefaultModelMetadataProvider.cs
index e7a2d454d8..710af66ebc 100644
--- a/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/DefaultModelMetadataProvider.cs
+++ b/src/Mvc/Mvc.Core/src/ModelBinding/Metadata/DefaultModelMetadataProvider.cs
@@ -190,7 +190,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
private ModelMetadataCacheEntry GetCacheEntry(PropertyInfo property, Type modelType)
{
return _typeCache.GetOrAdd(
- ModelMetadataIdentity.ForProperty(modelType, property.Name, property.DeclaringType),
+ ModelMetadataIdentity.ForProperty(property, modelType, property.DeclaringType),
_cacheEntryFactory);
}
@@ -275,8 +275,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
var propertyHelper = propertyHelpers[i];
var propertyKey = ModelMetadataIdentity.ForProperty(
+ propertyHelper.Property,
propertyHelper.Property.PropertyType,
- propertyHelper.Name,
key.ModelType);
var propertyEntry = CreateSinglePropertyDetails(propertyKey, propertyHelper);
diff --git a/src/Mvc/Mvc.Core/test/BindAttributeTest.cs b/src/Mvc/Mvc.Core/test/BindAttributeTest.cs
index 93b614e477..3dc6aa2fcb 100644
--- a/src/Mvc/Mvc.Core/test/BindAttributeTest.cs
+++ b/src/Mvc/Mvc.Core/test/BindAttributeTest.cs
@@ -1,8 +1,6 @@
// 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.Http;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
using Moq;
using Xunit;
@@ -27,7 +25,9 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding
var context = new DefaultModelBindingContext();
+#pragma warning disable CS0618 // Type or member is obsolete
var identity = ModelMetadataIdentity.ForProperty(typeof(int), property, typeof(string));
+#pragma warning restore CS0618 // Type or member is obsolete
context.ModelMetadata = new Mock(identity).Object;
// Act
diff --git a/src/Mvc/Mvc.Core/test/ModelBinding/Metadata/DefaultBindingMetadataProviderTest.cs b/src/Mvc/Mvc.Core/test/ModelBinding/Metadata/DefaultBindingMetadataProviderTest.cs
index 727cd31705..3a0756391d 100644
--- a/src/Mvc/Mvc.Core/test/ModelBinding/Metadata/DefaultBindingMetadataProviderTest.cs
+++ b/src/Mvc/Mvc.Core/test/ModelBinding/Metadata/DefaultBindingMetadataProviderTest.cs
@@ -161,7 +161,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
};
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(int), "Length", typeof(string)),
+ ModelMetadataIdentity.ForProperty(typeof(string).GetProperty(nameof(string.Length)), typeof(int), typeof(string)),
new ModelAttributes(new object[0], propertyAttributes, null));
var provider = new DefaultBindingMetadataProvider();
@@ -184,7 +184,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
};
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(int), "Length", typeof(string)),
+ ModelMetadataIdentity.ForProperty(typeof(string).GetProperty(nameof(string.Length)), typeof(int), typeof(string)),
new ModelAttributes(new object[0], propertyAttributes, null));
var provider = new DefaultBindingMetadataProvider();
@@ -207,7 +207,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
};
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(int), "Length", typeof(string)),
+ ModelMetadataIdentity.ForProperty(typeof(string).GetProperty(nameof(string.Length)), typeof(int), typeof(string)),
new ModelAttributes(new object[0], propertyAttributes, null));
var provider = new DefaultBindingMetadataProvider();
@@ -230,7 +230,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
};
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(int), "Length", typeof(string)),
+ ModelMetadataIdentity.ForProperty(typeof(string).GetProperty(nameof(string.Length)), typeof(int), typeof(string)),
new ModelAttributes(new object[0], propertyAttributes, null));
var provider = new DefaultBindingMetadataProvider();
@@ -253,7 +253,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
};
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(int), "Length", typeof(string)),
+ ModelMetadataIdentity.ForProperty(typeof(string).GetProperty(nameof(string.Length)), typeof(int), typeof(string)),
new ModelAttributes(new object[0], propertyAttributes, null));
var provider = new DefaultBindingMetadataProvider();
@@ -420,7 +420,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
};
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(int), "Length", typeof(string)),
+ ModelMetadataIdentity.ForProperty(typeof(string).GetProperty(nameof(string.Length)), typeof(int), typeof(string)),
new ModelAttributes(new object[0], propertyAttributes, null));
var provider = new DefaultBindingMetadataProvider();
@@ -438,7 +438,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
{
// Arrange
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(string), "Property", typeof(BindRequiredOnClass)),
+ ModelMetadataIdentity.ForProperty(typeof(BindRequiredOnClass).GetProperty(nameof(BindRequiredOnClass.Property)), typeof(int), typeof(BindRequiredOnClass)),
new ModelAttributes(new object[0], new object[0], null));
var provider = new DefaultBindingMetadataProvider();
@@ -456,7 +456,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
{
// Arrange
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(string), "Property", typeof(BindNeverOnClass)),
+ ModelMetadataIdentity.ForProperty(typeof(BindNeverOnClass).GetProperty(nameof(BindNeverOnClass.Property)), typeof(int), typeof(BindNeverOnClass)),
new ModelAttributes(new object[0], new object[0], null));
var provider = new DefaultBindingMetadataProvider();
@@ -474,7 +474,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
{
// Arrange
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(string), "Property", typeof(InheritedBindNeverOnClass)),
+ ModelMetadataIdentity.ForProperty(typeof(BindNeverOnClass).GetProperty(nameof(BindNeverOnClass.Property)), typeof(int), typeof(BindNeverOnClass)),
new ModelAttributes(new object[0], new object[0], null));
var provider = new DefaultBindingMetadataProvider();
@@ -497,7 +497,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
};
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(string), "Property", typeof(BindNeverOnClass)),
+ ModelMetadataIdentity.ForProperty(typeof(BindNeverOnClass).GetProperty(nameof(BindNeverOnClass.Property)), typeof(int), typeof(BindNeverOnClass)),
new ModelAttributes(new object[0], propertyAttributes, null));
var provider = new DefaultBindingMetadataProvider();
@@ -520,7 +520,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
};
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(string), "Property", typeof(BindNeverOnClass)),
+ ModelMetadataIdentity.ForProperty(typeof(BindNeverOnClass).GetProperty(nameof(BindNeverOnClass.Property)), typeof(int), typeof(BindNeverOnClass)),
new ModelAttributes(new object[0], propertyAttributes, null));
var provider = new DefaultBindingMetadataProvider();
@@ -543,7 +543,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
};
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(string), "Property", typeof(InheritedBindNeverOnClass)),
+ ModelMetadataIdentity.ForProperty(typeof(InheritedBindNeverOnClass).GetProperty(nameof(InheritedBindNeverOnClass.Property)), typeof(int), typeof(InheritedBindNeverOnClass)),
new ModelAttributes(new object[0], propertyAttributes, null));
var provider = new DefaultBindingMetadataProvider();
@@ -566,7 +566,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
};
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(string), "Property", typeof(BindRequiredOnClass)),
+ ModelMetadataIdentity.ForProperty(typeof(BindRequiredOnClass).GetProperty(nameof(BindRequiredOnClass.Property)), typeof(int), typeof(BindRequiredOnClass)),
new ModelAttributes(new object[0], propertyAttributes, null));
var provider = new DefaultBindingMetadataProvider();
@@ -585,7 +585,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
{
// Arrange
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(string), "Property", typeof(BindRequiredOverridesInheritedBindNever)),
+ ModelMetadataIdentity.ForProperty(typeof(BindRequiredOverridesInheritedBindNever).GetProperty(nameof(BindRequiredOverridesInheritedBindNever.Property)), typeof(int), typeof(BindRequiredOverridesInheritedBindNever)),
new ModelAttributes(new object[0], new object[0], null));
var provider = new DefaultBindingMetadataProvider();
@@ -641,7 +641,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
};
var context = new BindingMetadataProviderContext(
- ModelMetadataIdentity.ForProperty(typeof(int), "Length", typeof(string)),
+ ModelMetadataIdentity.ForProperty(typeof(string).GetProperty(nameof(string.Length)), typeof(int), typeof(string)),
new ModelAttributes(typeAttributes, new object[0], null));
// These values shouldn't be changed since this is a Type-Metadata
diff --git a/src/Mvc/Mvc.Core/test/ModelBinding/Metadata/DefaultModelMetadataTest.cs b/src/Mvc/Mvc.Core/test/ModelBinding/Metadata/DefaultModelMetadataTest.cs
index cace016898..b3d87dbead 100644
--- a/src/Mvc/Mvc.Core/test/ModelBinding/Metadata/DefaultModelMetadataTest.cs
+++ b/src/Mvc/Mvc.Core/test/ModelBinding/Metadata/DefaultModelMetadataTest.cs
@@ -103,7 +103,7 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
var provider = new EmptyModelMetadataProvider();
var detailsProvider = new EmptyCompositeMetadataDetailsProvider();
- var key = ModelMetadataIdentity.ForProperty(typeof(string), "Message", typeof(Exception));
+ var key = ModelMetadataIdentity.ForProperty(typeof(Exception).GetProperty(nameof(Exception.Message)), typeof(string), typeof(Exception));
var cache = new DefaultMetadataDetails(key, new ModelAttributes(new object[0], new object[0], null));
// Act
@@ -123,8 +123,8 @@ namespace Microsoft.AspNetCore.Mvc.ModelBinding.Metadata
var detailsProvider = new EmptyCompositeMetadataDetailsProvider();
var key = ModelMetadataIdentity.ForProperty(
+ typeof(TypeWithProperties).GetProperty(nameof(TypeWithProperties.PublicGetPublicSetProperty)),
typeof(string),
- nameof(TypeWithProperties.PublicGetPublicSetProperty),
typeof(TypeWithProperties));
var attributes = new ModelAttributes(Array.Empty