Skip to content

Commit 07fabde

Browse files
committed
Part 3 of aspnet#2776 - revert a6ce9ab and add
some more tests. This change reverts the behavior change from a6ce9ab and adds more tests around the scneario that was actually broken. The right behavior is that unconvertable values result in a validation error. There's no special behavior around value types and required values.
1 parent 27f7f3d commit 07fabde

File tree

14 files changed

+162
-89
lines changed

14 files changed

+162
-89
lines changed

src/Microsoft.AspNet.Mvc.Core/ModelBinding/Metadata/BindingMetadata.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,9 @@ public class BindingMetadata
3838
/// <summary>
3939
/// Gets or sets a value indicating whether or not the request must contain a value for the model.
4040
/// Will be ignored if the model metadata being created does not represent a property.
41-
/// See <see cref="ModelMetadata.IsBindingRequired"/>. If <c>null</c>, the value of
42-
/// <see cref="ModelMetadata.IsBindingRequired"/> will be computed based on
43-
/// <see cref="ModelMetadata.ModelType"/>.
41+
/// See <see cref="ModelMetadata.IsBindingRequired"/>.
4442
/// </summary>
45-
public bool? IsBindingRequired { get; set; }
43+
public bool IsBindingRequired { get; set; }
4644

4745
/// <summary>
4846
/// Gets or sets a value indicating whether or not the model is read-only. Will be ignored

src/Microsoft.AspNet.Mvc.Core/ModelBinding/Metadata/DefaultModelMetadata.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -341,14 +341,9 @@ public override bool IsBindingRequired
341341
{
342342
_isBindingRequired = false;
343343
}
344-
else if (BindingMetadata.IsBindingRequired.HasValue)
345-
{
346-
_isBindingRequired = BindingMetadata.IsBindingRequired;
347-
}
348344
else
349345
{
350-
// Default to IsBindingRequired = true for value types.
351-
_isBindingRequired = !AllowsNullValue(ModelType);
346+
_isBindingRequired = BindingMetadata.IsBindingRequired;
352347
}
353348
}
354349

src/Microsoft.AspNet.Mvc.Formatters.Xml/DataMemberRequiredBindingMetadataProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public void GetBindingMetadata([NotNull] BindingMetadataProviderContext context)
2222
return;
2323
}
2424

25-
if (context.BindingMetadata.IsBindingRequired == true)
25+
if (context.BindingMetadata.IsBindingRequired)
2626
{
2727
// This value is already required, no need to look at attributes.
2828
return;

test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/Metadata/DefaultModelMetadataTest.cs

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public void DefaultValues()
3939
Assert.False(metadata.HideSurroundingHtml);
4040
Assert.True(metadata.HtmlEncode);
4141
Assert.True(metadata.IsBindingAllowed);
42-
Assert.False(metadata.IsBindingRequired); // Defaults to false for reference types
42+
Assert.False(metadata.IsBindingRequired);
4343
Assert.False(metadata.IsComplexType);
4444
Assert.False(metadata.IsCollectionType);
4545
Assert.False(metadata.IsEnum);
@@ -223,49 +223,6 @@ public void IsBindingRequired_ReturnsFalse_ForTypes(Type modelType)
223223
Assert.False(isBindingRequired);
224224
}
225225

226-
[Theory]
227-
[InlineData(typeof(string))]
228-
[InlineData(typeof(IDisposable))]
229-
[InlineData(typeof(Nullable<int>))]
230-
public void IsBindingRequired_ReturnsFalse_ForNullablePropertyTypes(Type modelType)
231-
{
232-
// Arrange
233-
var provider = new EmptyModelMetadataProvider();
234-
var detailsProvider = new EmptyCompositeMetadataDetailsProvider();
235-
236-
var key = ModelMetadataIdentity.ForProperty(modelType, "Test", typeof(string));
237-
var cache = new DefaultMetadataDetails(key, new ModelAttributes(new object[0]));
238-
239-
var metadata = new DefaultModelMetadata(provider, detailsProvider, cache);
240-
241-
// Act
242-
var isBindingRequired = metadata.IsBindingRequired;
243-
244-
// Assert
245-
Assert.False(isBindingRequired);
246-
}
247-
248-
[Theory]
249-
[InlineData(typeof(int))]
250-
[InlineData(typeof(DayOfWeek))]
251-
public void IsBindingRequired_ReturnsTrue_ForNonNullablePropertyTypes(Type modelType)
252-
{
253-
// Arrange
254-
var provider = new EmptyModelMetadataProvider();
255-
var detailsProvider = new EmptyCompositeMetadataDetailsProvider();
256-
257-
var key = ModelMetadataIdentity.ForProperty(modelType, "Test", typeof(string));
258-
var cache = new DefaultMetadataDetails(key, new ModelAttributes(new object[0]));
259-
260-
var metadata = new DefaultModelMetadata(provider, detailsProvider, cache);
261-
262-
// Act
263-
var isBindingRequired = metadata.IsBindingRequired;
264-
265-
// Assert
266-
Assert.True(isBindingRequired);
267-
}
268-
269226
[Theory]
270227
[InlineData(typeof(string))]
271228
[InlineData(typeof(IDisposable))]

test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/MutableObjectModelBinderTest.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,7 @@ public void ProcessDto_ValueTypeProperty_TriesToSetNullModel_CapturesException()
10501050
}
10511051

10521052
[Fact]
1053-
public void ProcessDto_ValueTypeProperty_NoValue_Error()
1053+
public void ProcessDto_ValueTypeProperty_NoValue_NoError()
10541054
{
10551055
// Arrange
10561056
var model = new Person();
@@ -1083,14 +1083,7 @@ public void ProcessDto_ValueTypeProperty_NoValue_Error()
10831083
testableBinder.ProcessDto(bindingContext, dto, modelValidationNode);
10841084

10851085
// Assert
1086-
Assert.False(modelState.IsValid);
1087-
1088-
var entry = modelState["theModel." + nameof(Person.ValueTypeRequiredWithDefaultValue)];
1089-
var error = Assert.Single(entry.Errors);
1090-
Assert.Equal(
1091-
$"A value for the '{nameof(Person.ValueTypeRequiredWithDefaultValue)}' property was not provided.",
1092-
error.ErrorMessage);
1093-
Assert.Null(error.Exception);
1086+
Assert.True(modelState.IsValid);
10941087
}
10951088

10961089
[Fact]

test/Microsoft.AspNet.Mvc.FunctionalTests/HtmlGenerationTest.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,12 +196,11 @@ public async Task ValidationTagHelpers_GeneratesExpectedSpansAndDivs()
196196
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Customer/HtmlGeneration_Customer");
197197
var nameValueCollection = new List<KeyValuePair<string, string>>
198198
{
199-
new KeyValuePair<string,string>("Number", "0"),
199+
new KeyValuePair<string,string>("Number", string.Empty),
200200
new KeyValuePair<string,string>("Name", string.Empty),
201201
new KeyValuePair<string,string>("Email", string.Empty),
202202
new KeyValuePair<string,string>("PhoneNumber", string.Empty),
203-
new KeyValuePair<string,string>("Password", string.Empty),
204-
new KeyValuePair<string, string>("Gender", "Female"),
203+
new KeyValuePair<string,string>("Password", string.Empty)
205204
};
206205
request.Content = new FormUrlEncodedContent(nameValueCollection);
207206

test/Microsoft.AspNet.Mvc.FunctionalTests/ModelBindingFromQueryTest.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,8 @@ public async Task FromQuery_NonExistingValueAddsValidationErrors_OnProperty_Usin
122122
// Assert
123123
var body = await response.Content.ReadAsStringAsync();
124124
var result = JsonConvert.DeserializeObject<Result>(body);
125-
126-
Assert.Collection(
127-
result.ModelStateErrors,
128-
e => Assert.Equal("TestEmployees[0].EmployeeId", e),
129-
e => Assert.Equal("TestEmployees[0].EmployeeTaxId", e),
130-
e => Assert.Equal("TestEmployees[0].Age", e));
125+
var error = Assert.Single(result.ModelStateErrors);
126+
Assert.Equal("TestEmployees[0].EmployeeId", error);
131127
}
132128
}
133129
}

test/Microsoft.AspNet.Mvc.FunctionalTests/ModelBindingTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2218,7 +2218,7 @@ public async Task TryUpdateModel_ClearsModelStateEntries()
22182218
// Arrange
22192219
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
22202220
var client = server.CreateClient();
2221-
var url = "http://localhost/TryUpdateModel/TryUpdateModel_ClearsModelStateEntries?id=5&price=1";
2221+
var url = "http://localhost/TryUpdateModel/TryUpdateModel_ClearsModelStateEntries";
22222222

22232223
// Act
22242224
var response = await client.GetAsync(url);

test/Microsoft.AspNet.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Customer.Index.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<form action="/Customer/HtmlGeneration_Customer" method="post">
44
<div>
55
<label class="order" for="Number">Number</label>
6-
<input class="form-control input-validation-error" type="number" data-val="true" data-val-range="The field Number must be between 1 and 100." data-val-range-max="100" data-val-range-min="1" data-val-required="The Number field is required." id="Number" name="Number" value="0" />
7-
<span class="field-validation-error" data-valmsg-for="Number" data-valmsg-replace="true">The field Number must be between 1 and 100.</span>
6+
<input class="form-control input-validation-error" type="number" data-val="true" data-val-range="The field Number must be between 1 and 100." data-val-range-max="100" data-val-range-min="1" data-val-required="The Number field is required." id="Number" name="Number" value="" />
7+
<span class="field-validation-error" data-valmsg-for="Number" data-valmsg-replace="true">The value &#x27;&#x27; is invalid.</span>
88
</div>
99
<div>
1010
<label class="order" for="Name">Name</label>
@@ -27,10 +27,10 @@
2727
<div>
2828
<label class="order" for="Gender">Gender</label>
2929
<input type="radio" value="Male" data-val="true" data-val-required="The Gender field is required." id="Gender" name="Gender" /> Male
30-
<input type="radio" value="Female" checked="checked" id="Gender" name="Gender" /> Female
30+
<input type="radio" value="Female" id="Gender" name="Gender" /> Female
3131
<span class="field-validation-valid" data-valmsg-for="Gender" data-valmsg-replace="true"></span>
3232
</div>
33-
<div class="order validation-summary-errors" data-valmsg-summary="true"><ul><li>The field Number must be between 1 and 100.</li>
33+
<div class="order validation-summary-errors" data-valmsg-summary="true"><ul><li>The value &#x27;&#x27; is invalid.</li>
3434
<li>The Password field is required.</li>
3535
</ul></div>
3636
<div class="order validation-summary-errors"><ul><li style="display:none"></li>

test/Microsoft.AspNet.Mvc.IntegrationTests/BodyValidationIntegrationTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public async Task FromBodyOnActionParameter_EmptyBody_BindsToNullValue()
108108
private class Person4
109109
{
110110
[FromBody]
111-
[BindingBehavior(BindingBehavior.Optional)]
111+
[Required]
112112
public int Address { get; set; }
113113
}
114114

0 commit comments

Comments
 (0)