Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net Web API Validation Attributes on DTO?

I'm using ASP.Net Web API and the Code First Entity Framework and from what I've read you should typically be exposing DTO objects rather than the entity objects directly in your action methods (according to http://www.asp.net/web-api/overview/data/using-web-api-with-entity-framework/part-5).

So in one case I'm working on, to avoid the problem of "over-posting" as described in the link above I've created a DTO object with almost all the same properties as the model object. What I'm wondering however is do I need to duplicate all the same sets of validation attributes (eg. [Required], [Range(N,M)], etc. for both the DTO and model properties? Initially I was hoping not to (to avoid duplication) but you need the validation attributes on the DTO if you want to leverage the binding validation (ie. ModelState.IsValid) and on the main model if you want your database to be created with the appropriate constraints ([Required] -> not null, etc.)

Is there no better way?

Also, are there some attributes that Entity does use but the model binding validation does not use? For example, while [Range(n,m)] will clearly affect validation on some client input, does entity care about it at all (it doesn't seem to affect the created DB schema from what I can tell?)

like image 679
Neil Sainsbury Avatar asked Dec 03 '14 05:12

Neil Sainsbury


People also ask

What exactly does ModelState IsValid do?

ModelState. IsValid indicates if it was possible to bind the incoming values from the request to the model correctly and whether any explicitly specified validation rules were broken during the model binding process.

What is DTO in Web API?

Data Transfer Objects are used to transfer data between the Application Layer and the Presentation Layer. The Presentation Layer calls an Application Service method with a Data Transfer Object (DTO).

What is ApiController attribute?

The [ApiController] attribute applies inference rules for the default data sources of action parameters. These rules save you from having to identify binding sources manually by applying attributes to the action parameters.


1 Answers

The entities should only have the attributes which are actually having an impact on the database. The DTOs should not have any attributes for validation except for the DataMemberAttribute to define if a property is required and in which order it should be displayed etc. For OData you also have to set the KeyAttribute. The models should have the validation attributes. Because the DTOs and the models are probably almost identical you create for each dto which needs to be validated a model and just swap the dto's value to the model's object. Now you can validate it, if you are not using ValidationAttributes for the models you can validate them for example with FluentValidation

So long story short:

  • Entities only get the attributes which actually impact the database's schema

  • DTOs are simple objects with no validation logic, except for the DataMemberAttribute

  • Models should have the validation attributes (only if needed, not needed when using FluentValidation)

The workflow for POST will be: -> DTO comes in -> Swap dto to Model -> Validate the model -> Swap model to entity -> Store entity in database -> Use the updated entity and swap it to a new dto -> Return the dto

Greetings, Voltaic

like image 147
Voltaic Avatar answered Nov 04 '22 11:11

Voltaic