Reputation: 2440
I have a very simple 3-tier layer ASP.NET Core WebAPI
application:
Entities
, Data interfaces
, Services
and DTO
objects (which are the only input and output objects). So "the interface of the Domain" are Services that accepts input DTOs and returns output DTOs.Data interfaces
(Data repositories) and CodeFirst Migrations.The WebAPI project returns "Output" DTOs in Controllers. For endpoints that accepts payload, "Input" DTOs are used. Controllers are very much similar to the Services from the Domain. Controllers expose Domain Services to the world (obviously, the interface of the Domain).
But then comes the Validation... I'm familiar with FluentValidation and with the ASP.NET Core plumbing - it's an awesome middleware:
services.AddControllers()
.AddFluentValidation(opt =>
{
opt.RegisterValidatorsFromAssemblyContaining(typeof(PersonInputValidator));
});
I implement validation for each "Input" DTO and this works great, BUT... I'm not sure if this is enough. If you take any Service class, it's pretty much not validated. It's .NET Core middleware that technically validates the input to the Controller.
Should I "double-validate" within Services again? If so, is there a smooth way to reuse Validators I already have?
Upvotes: 4
Views: 10523
Reputation: 493
FluentValidations can be used in controllers while also keeping them lean. In the business layer, other validation rules can also be added but the model state is checked in the WebApi level which is the gateway to the system. FluentValidation uses middleware so the controller is not even hit if validation fails. I also suggest implementing middleware which translates any exceptions thrown by the business layer into appropriate http status codes, which also leaves your controllers very clean. In the business layer sometimes validation rules are also used, such as when you want to check that dependent data is present.
Upvotes: 2
Reputation: 3183
With a service layer and presentation layer, I would normally do the FV implementation/dto validation at the service layer. That way the services can be reused and the validation goes with them. It also allows you to keep your controllers lean. In your controllers there may be scope to have presentation layer specific checks/validation eg the model binding failed. But that can just be a basic model state implementation, I wouldn't get FV onto this.
Upvotes: 2
Reputation: 7019
You should never have to run validations twice. The data from your web API should be validated. If you ever use your services with any other interface besides a web API, you could implement your fluent validations there too. Here is a good example for implementing fluent validations: https://github.com/jasontaylordev/NorthwindTraders
Upvotes: 6