Fix #2986 - Make ModelMetadata getters null-safe

This commit is contained in:
Ryan Nowak 2015-08-19 08:37:18 -07:00
parent 8b5bb0133d
commit b5c9d905d9
3 changed files with 21 additions and 6 deletions

View File

@ -122,7 +122,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata
var propertyEntry = new DefaultMetadataDetails(propertyKey, attributes);
if (propertyHelper.Property.CanRead && propertyHelper.Property.GetMethod?.IsPublic == true)
{
propertyEntry.PropertyGetter = propertyHelper.ValueGetter;
var getter = PropertyHelper.MakeNullSafeFastPropertyGetter(propertyHelper.Property);
propertyEntry.PropertyGetter = getter;
}
if (propertyHelper.Property.CanWrite &&

View File

@ -287,10 +287,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// instances or overwrite inner properties that are not bound. No need for this with simple values
// because they will be overwritten if binding succeeds. Arrays are never reused because they cannot
// be resized.
//
// ModelMetadata.PropertyGetter is not null safe; use it only if Model is non-null.
if (bindingContext.Model != null &&
propertyMetadata.PropertyGetter != null &&
if (propertyMetadata.PropertyGetter != null &&
propertyMetadata.IsComplexType &&
!propertyMetadata.ModelType.IsArray)
{

View File

@ -140,6 +140,23 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata
Assert.Equal(typeof(string), propertyMetadata.ModelType);
}
[Fact]
public void GetMetadataForProperties_PropertyGetter_IsNullSafe()
{
// Arrange
var provider = CreateProvider();
// Act
var metadata = provider.GetMetadataForProperties(typeof(ModelType));
// Assert
foreach (var property in metadata)
{
Assert.NotNull(property.PropertyGetter);
Assert.Null(property.PropertyGetter(null));
}
}
private static DefaultModelMetadataProvider CreateProvider()
{
return new DefaultModelMetadataProvider(new EmptyCompositeMetadataDetailsProvider());
@ -149,7 +166,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata
private class ModelType
{
[Model("OnProperty")]
public PropertyType Property1 { get; }
public PropertyType Property1 { get; } = new PropertyType();
public PropertyType Property2 { get; set; }
}