Fix for #2357 : We prevent assigining null values to non nullable controller properties.
This commit is contained in:
parent
53ef8258bb
commit
86fcacea92
|
|
@ -111,7 +111,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
propertyHelper.SetValue(controller, property.Value);
|
// Do not set the property if the type is a non nullable type.
|
||||||
|
if (property.Value != null || propertyHelper.Property.PropertyType.AllowsNullValue())
|
||||||
|
{
|
||||||
|
propertyHelper.SetValue(controller, property.Value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetActionArgumentsAsync_DoesNotAddActionArguments_IfBinderReturnsFalse()
|
public async Task BindActionArgumentsAsync_DoesNotAddActionArguments_IfBinderReturnsFalse()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var actionDescriptor = GetActionDescriptor();
|
var actionDescriptor = GetActionDescriptor();
|
||||||
|
|
@ -88,7 +88,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetActionArgumentsAsync_DoesNotAddActionArguments_IfBinderDoesNotSetModel()
|
public async Task BindActionArgumentsAsync_DoesNotAddActionArguments_IfBinderDoesNotSetModel()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var actionDescriptor = GetActionDescriptor();
|
var actionDescriptor = GetActionDescriptor();
|
||||||
|
|
@ -127,7 +127,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetActionArgumentsAsync_AddsActionArguments_IfBinderReturnsTrue()
|
public async Task BindActionArgumentsAsync_AddsActionArguments_IfBinderReturnsTrue()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
Func<object, int> method = foo => 1;
|
Func<object, int> method = foo => 1;
|
||||||
|
|
@ -174,7 +174,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetActionArgumentsAsync_CallsValidator_IfModelBinderSucceeds()
|
public async Task BindActionArgumentsAsync_CallsValidator_IfModelBinderSucceeds()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var actionDescriptor = GetActionDescriptor();
|
var actionDescriptor = GetActionDescriptor();
|
||||||
|
|
@ -204,7 +204,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetActionArgumentsAsync_DoesNotCallValidator_IfModelBinderFails()
|
public async Task BindActionArgumentsAsync_DoesNotCallValidator_IfModelBinderFails()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
Func<object, int> method = foo => 1;
|
Func<object, int> method = foo => 1;
|
||||||
|
|
@ -246,7 +246,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetActionArgumentsAsync_CallsValidator_ForControllerProperties_IfModelBinderSucceeds()
|
public async Task BindActionArgumentsAsync_CallsValidator_ForControllerProperties_IfModelBinderSucceeds()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var actionDescriptor = GetActionDescriptor();
|
var actionDescriptor = GetActionDescriptor();
|
||||||
|
|
@ -276,7 +276,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetActionArgumentsAsync_DoesNotCallValidator_ForControllerProperties_IfModelBinderFails()
|
public async Task BindActionArgumentsAsync_DoesNotCallValidator_ForControllerProperties_IfModelBinderFails()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
Func<object, int> method = foo => 1;
|
Func<object, int> method = foo => 1;
|
||||||
|
|
@ -318,7 +318,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetActionArgumentsAsync_SetsControllerProperties()
|
public async Task BindActionArgumentsAsync_SetsControllerProperties()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var actionDescriptor = GetActionDescriptor();
|
var actionDescriptor = GetActionDescriptor();
|
||||||
|
|
@ -343,6 +343,44 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
Assert.Null(controller.UnmarkedProperty);
|
Assert.Null(controller.UnmarkedProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task BindActionArgumentsAsync_DoesNotSetNullValues_ForNonNullableProperties()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var actionDescriptor = GetActionDescriptor();
|
||||||
|
actionDescriptor.BoundProperties.Add(
|
||||||
|
new ParameterDescriptor
|
||||||
|
{
|
||||||
|
Name = "ValueBinderMarkedProperty",
|
||||||
|
BindingInfo = new BindingInfo(),
|
||||||
|
ParameterType = typeof(int)
|
||||||
|
});
|
||||||
|
|
||||||
|
var actionContext = GetActionContext(actionDescriptor);
|
||||||
|
|
||||||
|
var binder = new Mock<IModelBinder>();
|
||||||
|
binder
|
||||||
|
.Setup(b => b.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
||||||
|
.Returns(Task.FromResult(
|
||||||
|
result: new ModelBindingResult(model: null, key: string.Empty, isModelSet: true)));
|
||||||
|
var actionBindingContext = new ActionBindingContext()
|
||||||
|
{
|
||||||
|
ModelBinder = binder.Object,
|
||||||
|
};
|
||||||
|
|
||||||
|
var argumentBinder = GetArgumentBinder();
|
||||||
|
var controller = new TestController();
|
||||||
|
|
||||||
|
// Some non default value.
|
||||||
|
controller.NotNullableProperty = -1;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await argumentBinder.BindActionArgumentsAsync(actionContext, actionBindingContext, controller);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(-1, controller.NotNullableProperty);
|
||||||
|
}
|
||||||
|
|
||||||
private static ActionContext GetActionContext(ActionDescriptor descriptor = null)
|
private static ActionContext GetActionContext(ActionDescriptor descriptor = null)
|
||||||
{
|
{
|
||||||
return new ActionContext(
|
return new ActionContext(
|
||||||
|
|
@ -400,6 +438,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
[ValueProviderMetadata]
|
[ValueProviderMetadata]
|
||||||
public string ValueBinderMarkedProperty { get; set; }
|
public string ValueBinderMarkedProperty { get; set; }
|
||||||
|
|
||||||
|
[CustomBindingSource]
|
||||||
|
public int NotNullableProperty { get; set; }
|
||||||
|
|
||||||
public Person ActionWithBodyParam([FromBody] Person bodyParam)
|
public Person ActionWithBodyParam([FromBody] Person bodyParam)
|
||||||
{
|
{
|
||||||
return bodyParam;
|
return bodyParam;
|
||||||
|
|
@ -421,6 +462,11 @@ namespace Microsoft.AspNet.Mvc.Core.Test
|
||||||
public BindingSource BindingSource { get { return BindingSource.Body; } }
|
public BindingSource BindingSource { get { return BindingSource.Body; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class CustomBindingSourceAttribute : Attribute, IBindingSourceMetadata
|
||||||
|
{
|
||||||
|
public BindingSource BindingSource { get { return BindingSource.Custom; } }
|
||||||
|
}
|
||||||
|
|
||||||
private class ValueProviderMetadataAttribute : Attribute, IBindingSourceMetadata
|
private class ValueProviderMetadataAttribute : Attribute, IBindingSourceMetadata
|
||||||
{
|
{
|
||||||
public BindingSource BindingSource { get { return BindingSource.Query; } }
|
public BindingSource BindingSource { get { return BindingSource.Query; } }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue