If you need to validate the inputs to your api actions I really do recommend trying the FluentValidation.AspNetCore package. Its very easy to integrate and you can do quite powerful validations. As an example I created a Person controller.
[Route(api/[controller])]
[ApiController]
public class PersonController : ControllerBase
{
[HttpPost]
public async Task<ActionResult> Post([FromBody] PersonViewModel person)
{
//Do something
return Ok();
}
}
public class PersonViewModel
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }
}
In this example I will put all my validation classes in the same executing assembly so I register it in the ConfigureServices method as:
services.AddControllers()
.AddFluentValidation(fv =>
fv.RegisterValidatorsFromAssembly(Assembly.GetExecutingAssembly()));
Then I just need to create a class that implements the AbstractValidator interface.
public class PersonViewModelValidator : AbstractValidator<PersonViewModel>
{
public PersonViewModelValidator()
{
RuleFor(x => x.Age).GreaterThan(18);
RuleFor(x => x.Email).EmailAddress();
}
}
This validator makes sure that the age is greater than 18 and the email address is a valid email. It has a lot of validation options so its quite possible to do quite complex validations.
If I was to post the following json to the action:
{
"name":"John",
"age":19,
"email":"someEmail"
}
I get back a JSON result:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|acba2675-4aa6f07682c5ca37.",
"errors":{
"Email":[
"'Email' is not a valid email address."
]
}
}
What is nice is that you don't pollute your controllers will repeated validation code which makes them much cleaner.