问题
In .NET Core I have a model that looks like this.
public class Home
{
[Required]
public int Number {get;set;}
public Address Address {get;set;} // This is not required
}
public class Address
{
[Required]
public string Street {get;set;}
public IFormFile Picture {get;set;}
}
In a controller method that looks like this
[HttpPost]
public string AddHomes([FromForm]List<Home> homes)
{
if(!ModelState.IsValid)
{
return BadRequest();
}
// Do some saving
return Ok();
}
In a form request that looks like this
homes.Index: 0
homes[0].number: 1
In .NET Core 2.2 the first home in the list is invalid. It was working in .NET Core 2.1
I want the [Required] attribute to only be validated if the Address is not null
. So a Home can either have an Address with a Street or no Address at all.
Is this achievable in .NET Core 2.2?
Note: Updated example to reproduce error. It seems the inclusion of IFormFile causes the Address Class to initialize itself.
{
"errors": {
"homes[0].Address.Street": [
"The Street field is required."
]
},
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "80000009-0003-ff00-b63f-84710c7967bb"
}
I also opened an issue some time ago for this: https://github.com/aspnet/AspNetCore/issues/9321 if anybody wants to follow up.
回答1:
The behavior you're wanting is the behavior for null reference properties, and it has not changed in ASP.NET Core 2.2. The properties on the referenced class are only validated if the reference itself is non-null. If this isn't working for you, then the only conclusion is that this reference property does have a value. It might just be a default instantiation (i.e. new Foo()
), with none of the sub properties actually defined, but that is enough to trigger validation.
First, ensure that you are not setting a default value for the property, or otherwise providing it a default through the contructor, for example. In other words, if you have something like:
public Bar Bar { get; set; } = new Bar();
Or,
public Foo()
{
Bar = new Bar();
}
Remove that.
Also, realize that if anything is posted for that reference property, then everything comes into play. Even if you just have some hidden property like:
<input type="hidden" asp-for="Bar.Id" />
If any one property on the reference is posted, even if it, itself, is not valid, all validation on the class will come into play.
来源:https://stackoverflow.com/questions/55635041/net-core-2-2-required-properties-when-object-is-not-null-complex-nested-model