Fix for #1694 issue : Removed prefix for ModelState keys for FromBody parameters

This commit is contained in:
Kirthi Krishnamraju 2015-02-19 10:53:40 -08:00
parent 27bdec40a6
commit 2b246e7acc
9 changed files with 63 additions and 35 deletions

View File

@ -57,7 +57,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var unsupportedContentType = Resources.FormatUnsupportedContentType(
bindingContext.OperationBindingContext.HttpContext.Request.ContentType);
bindingContext.ModelState.AddModelError(bindingContext.ModelName, unsupportedContentType);
return new ModelBindingResult(null, bindingContext.ModelName, isModelSet: false);
return new ModelBindingResult(model: null, key: bindingContext.ModelName, isModelSet: false);
}
object model = null;
@ -72,7 +72,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
return new ModelBindingResult(model: null, key: bindingContext.ModelName, isModelSet: false);
}
return new ModelBindingResult(model, bindingContext.ModelName, isModelSet: true);
// key is empty to ensure that the model name is not used as a prefix for validation.
return new ModelBindingResult(model, key: string.Empty, isModelSet: true);
}
private object GetDefaultValueForType(Type modelType)

View File

@ -158,6 +158,38 @@ namespace Microsoft.AspNet.Mvc
Assert.Equal("Your input is bad!", errorMessage);
}
[Fact]
public async Task NullFormatterError_AddedToModelState()
{
// Arrange
var httpContext = new DefaultHttpContext();
httpContext.Request.ContentType = "text/xyz";
var provider = new TestModelMetadataProvider();
provider.ForType<Person>().BindingDetails(d => d.BindingSource = BindingSource.Body);
var bindingContext = GetBindingContext(
typeof(Person),
inputFormatter: null,
httpContext: httpContext,
metadataProvider: provider);
var binder = bindingContext.OperationBindingContext.ModelBinder;
// Act
var binderResult = await binder.BindModelAsync(bindingContext);
// Assert
// Returns true because it understands the metadata type.
Assert.NotNull(binderResult);
Assert.False(binderResult.IsModelSet);
Assert.Null(binderResult.Model);
Assert.True(bindingContext.ModelState.ContainsKey("someName"));
var errorMessage = bindingContext.ModelState["someName"].Errors[0].ErrorMessage;
Assert.Equal("Unsupported content type 'text/xyz'.", errorMessage);
}
private static ModelBindingContext GetBindingContext(
Type modelType,
IInputFormatter inputFormatter = null,

View File

@ -60,8 +60,8 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
"<Employee xmlns=\"http://schemas.datacontract.org/2004/07/FormatterWebSite\">" +
"<Id>2</Id><Name>foo</Name></Employee>";
var expectedOutput = "{\"employee.Id\":[\"The field Id must be between 10 and 100." +
"\"],\"employee.Name\":[\"The field Name must be a string or array type with" +
var expectedOutput = "{\"Id\":[\"The field Id must be between 10 and 100." +
"\"],\"Name\":[\"The field Name must be a string or array type with" +
" a minimum length of '15'.\"]}";
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/SerializableError/CreateEmployee");
request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));

View File

@ -1139,9 +1139,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
Assert.Equal(new[] {
"The field Year must be between 1980 and 2034.",
"Year is invalid"
}, modelStateErrors["model.Year"]);
}, modelStateErrors["Year"]);
var vinError = Assert.Single(modelStateErrors["model.Vin"]);
var vinError = Assert.Single(modelStateErrors["Vin"]);
Assert.Equal("The Vin field is required.", vinError);
}
@ -1174,7 +1174,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
var modelStateErrors = JsonConvert.DeserializeObject<IDictionary<string, IEnumerable<string>>>(body);
var item = Assert.Single(modelStateErrors);
Assert.Equal("model.InspectedDates", item.Key);
Assert.Equal("InspectedDates", item.Key);
var error = Assert.Single(item.Value);
Assert.Equal("Inspection date cannot be later than year of manufacture.", error);
}
@ -1772,14 +1772,14 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
new[]
{
":Required property 'Id' not found in JSON",
"rectangle.Lines:The Lines field is required."
"Lines:The Lines field is required."
}
},
{
"{\"Id\":10}",
new[]
{
"rectangle.Lines:The Lines field is required."
"Lines:The Lines field is required."
}
},
{

View File

@ -58,12 +58,12 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
var body = await response.Content.ReadAsStringAsync();
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
Assert.Equal(6, json.Count);
Assert.Equal("CompanyName cannot be null or empty.", json["product.CompanyName"]);
Assert.Equal("The field Price must be between 20 and 100.", json["product.Price"]);
Assert.Equal("The Category field is required.", json["product.Category"]);
Assert.Equal("The Contact Us field is required.", json["product.Contact"]);
Assert.Equal("The Detail2 field is required.", json["product.ProductDetails.Detail2"]);
Assert.Equal("The Detail3 field is required.", json["product.ProductDetails.Detail3"]);
Assert.Equal("CompanyName cannot be null or empty.", json["CompanyName"]);
Assert.Equal("The field Price must be between 20 and 100.", json["Price"]);
Assert.Equal("The Category field is required.", json["Category"]);
Assert.Equal("The Contact Us field is required.", json["Contact"]);
Assert.Equal("The Detail2 field is required.", json["ProductDetails.Detail2"]);
Assert.Equal("The Detail3 field is required.", json["ProductDetails.Detail3"]);
}
[Fact]
@ -85,7 +85,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
var body = await response.Content.ReadAsStringAsync();
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
Assert.Equal(1, json.Count);
Assert.Equal("The ProductDetails field is required.", json["product.ProductDetails"]);
Assert.Equal("The ProductDetails field is required.", json["ProductDetails"]);
}
[Fact]
@ -109,7 +109,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
var body = await response.Content.ReadAsStringAsync();
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
Assert.Equal(1, json.Count);
Assert.Equal("Product must be made in the USA if it is not named.", json["product"]);
Assert.Equal("Product must be made in the USA if it is not named.", json[""]);
}
[Fact]
@ -152,8 +152,8 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
var body = await response.Content.ReadAsStringAsync();
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
Assert.Equal(2, json.Count);
Assert.Equal("The field Price must be between 100 and 200.", json["software.Price"]);
Assert.Equal("The field Contact must be a string with a maximum length of 10.", json["software.Contact"]);
Assert.Equal("The field Price must be between 100 and 200.", json["Price"]);
Assert.Equal("The field Contact must be a string with a maximum length of 10.", json["Contact"]);
}
[Fact]
@ -176,7 +176,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
var body = await response.Content.ReadAsStringAsync();
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
Assert.Equal(1, json.Count);
Assert.Equal("Product must be made in the USA if it is not named.", json["software"]);
Assert.Equal("Product must be made in the USA if it is not named.", json[""]);
}
}
}

View File

@ -82,9 +82,9 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
var input = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<Employee xmlns=\"http://schemas.datacontract.org/2004/07/XmlFormattersWebSite.Models\">" +
"<Id>2</Id><Name>foo</Name></Employee>";
var expected = "<Error><employee.Id>The field Id must be between 10 and 100.</employee.Id>" +
"<employee.Name>The field Name must be a string or array type with a minimum " +
"length of '15'.</employee.Name></Error>";
var expected = "<Error><Id>The field Id must be between 10 and 100.</Id>" +
"<Name>The field Name must be a string or array type with a minimum " +
"length of '15'.</Name></Error>";
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/SerializableError/CreateEmployee");
request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse(acceptHeader));
request.Content = new StringContent(input, Encoding.UTF8, "application/xml-dcs");

View File

@ -26,7 +26,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
// Arrange
var server = TestHelper.CreateServer(_app, SiteName, _configureServices);
var client = server.CreateClient();
var input = "{ \"Price\": 2, \"Contact\": \"acvrdzersaererererfdsfdsfdsfsdf\", "+
var input = "{ \"Price\": 2, \"Contact\": \"acvrdzersaererererfdsfdsfdsfsdf\", " +
"\"ProductDetails\": {\"Detail1\": \"d1\", \"Detail2\": \"d2\", \"Detail3\": \"d3\"}}";
var content = new StringContent(input, Encoding.UTF8, "application/json");
var url =
@ -39,12 +39,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
// Assert
var body = await response.Content.ReadAsStringAsync();
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(body);
Assert.Equal(8, json.Count);
Assert.Equal("CompanyName cannot be null or empty.", json["product.CompanyName"]);
Assert.Equal("The field Price must be between 20 and 100.", json["product.Price"]);
Assert.Equal("The Category field is required.", json["product.Category"]);
Assert.Equal("The field Contact Us must be a string with a maximum length of 20." +
"The field Contact Us must match the regular expression '^[0-9]*$'.", json["product.Contact"]);
Assert.Equal(4, json.Count);
Assert.Equal("CompanyName cannot be null or empty.", json["CompanyName"]);
Assert.Equal("The field Price must be between 20 and 100.", json["Price"]);
Assert.Equal("The Category field is required.", json["Category"]);

View File

@ -118,7 +118,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
{
return string.Format(errorMessageFormat, kvp.Key, kvp.Value);
}).ToList();
expectedErrorMessages.Add("store.Address:The Address field is required.");
expectedErrorMessages.Add("Address:The Address field is required.");
// Act
var response = await client.PostAsync("http://localhost/Validation/CreateStore", content);

View File

@ -15,10 +15,10 @@ namespace FormatterWebSite
{
if (!ModelState.IsValid)
{
return Content(ModelState["user.Id"].Errors[0].ErrorMessage + "," +
ModelState["user.Name"].Errors[0].ErrorMessage + "," +
ModelState["user.Alias"].Errors[0].ErrorMessage + "," +
ModelState["user.Designation"].Errors[0].ErrorMessage);
return Content(ModelState["Id"].Errors[0].ErrorMessage + "," +
ModelState["Name"].Errors[0].ErrorMessage + "," +
ModelState["Alias"].Errors[0].ErrorMessage + "," +
ModelState["Designation"].Errors[0].ErrorMessage);
}
return Content("User has been registerd : " + user.Name);