Reputation: 1166
I have an issue with [BindRequired] attribute, it does not invalidate my model state:
public class PostModel
{
[BindRequired]
public DateTime Date { get; set; }
}
Controller:
[ApiController]
public class BindTestController : ControllerBase
{
[HttpPost("test")]
public IActionResult SetValue([FromBody] PostModel request)
{
if (!ModelState.IsValid)
return BadRequest();
return Ok();
}
}
if I post a body like this:
{}
My modelstate is valid.
What is the good way of validating that Date
is present on my body, and invalidate the model ?
Thanks
Upvotes: 1
Views: 1474
Reputation: 549
BindRequired
and Required
attributesThe BindRequired
and Required
attributes are often confused because they imply some form of “required-ness” for model properties. However, they serve different purposes and are used in different contexts. It is important to understand when to use them in order to correctly implement data validation and model-binding behavior.
BindRequired
attribute, from the
Microsoft.AspNetCore.Mvc.ModelBinding
namespace handles model binding
behavior. It is used to indicate that a property must be present in
the incoming data for binding to succeed. If the property is not
present in the incoming request, the model state becomes invalid.Required
, BindRequired
does not concern itself with validating the property’s content (whether empty
or null
)
but rather with its presence in the request. This is useful for
ensuring that key parts of the model are not omitted in the request.Example
using Microsoft.AspNetCore.Mvc.ModelBinding;
public class UpdateModel
{
[BindRequired]
public int Id { get; set; } // Must be present in the incoming request
}
Required
attribute is part of the
System.ComponentModel.DataAnnotations
namespace and is used
primarily for model validation. It ensures that a property has a
value; it is mainly used to enforce that a field should not be
null
or empty
during model validation.Required
attribute
does not have a value, the model state is considered invalid. This
attribute affects the server-side validation process and is also
used to generate client-side validation rules.Example
using System.ComponentModel.DataAnnotations;
public class RegisterModel
{
[Required]
public string Email { get; set; } // Must have a non-null/non-empty value
}
Use Required
Attribute when you need to ensure that a property is not empty or null (common for forms and data entry scenarios). Use BindRequired
when you need to ensure that certain data elements are actually present in the incoming request, typically important in APIs and data update scenarios.
Upvotes: 0
Reputation: 1625
Add the RequiredAttribute
to your DateTime
property, then you need to make the DateTime
nullable, otherwise you will get the default value for DateTime
which is {0001-01-01T00:00:00}
.
So basically do the followings:
public class PostModel
{
[Required]
public DateTime? Date { get; set; }
}
Regarding why the BindRequired
did not work, I think (not 100% sure, it is just what i think) that since you are using [ApiController]
, it first would use [FromBody]
by default, then the binding would happen after the Json.NET
deserialization, so when the deserialization
happens the DateTime value would be set to the Default(DateTime)
. To solve this you can use the old way as shown above instead of using BindRequired
, or add [JsonRequired]
.
Note: when you use [JsonRequired]
with [ApiController]
, validation happens before it hits your endpoint. Also note that BindRequired
works well with normal MVC Controller.
Upvotes: 2
Reputation: 702
You could use RequiredAttribute
instead of BindRequiredAttribute
. In ASP.NET Core, the latter is only applicable for “non body” parameters
Upvotes: 1