I'm learning ASP.NET Core 8 and trying to understand the best practices for applying validation attributes to data.
I have a situation where I'm using both a model and a DTO in my project. For example:
The model represents the structure of the data in my database.
The DTO is used to transfer data between layers (e.g., controllers and services).
I'm confused about where I should add the validation attributes. Should they be added to the model, the DTO, or both?
Would it be considered bad practice to duplicate validations in both classes?
Code Example:
//Model Class
public class User
{
public int Id { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
[EmailAddress]
public string Email { get; set; }
}
//DTO
public class CreateUserDto
{
[Required]
[StringLength(50)]
public string Name { get; set; }
[EmailAddress]
public string Email { get; set; }
}
So, is it necessary to duplicate the validation attributes in the CreateUserDto
, even though the same validations exist in the User
model?
I'm trying to follow good practices, but I'm unsure if duplicating validations across the model and DTO is the right approach.
Any advice on this would be greatly appreciated
I'm trying to follow good practices, but I'm unsure if duplicating validations across the model and DTO is the right approach.
You write that you're learning, and that's great! There's always a first time for everything, so the following is not at all meant as a criticism. You are asking about a known unknown, but when you're new to a topic, there are sometimes unknown unknowns, and I believe this may be the case here.
In software engineering and architecture, there are no singular 'good practices'. There are practices that are beneficial in a given context, and likely to be detrimental in other contexts. One example is the common use of having more than one model of data in a code base, such as is shown here.
I recently wrote a three-part article series that discusses alternatives. In short, if you have models that are sufficiently different, more than one class is warranted. In the case of the OP example, it looks as though the only difference is that the 'model' has an Id
property, in which case you may instead want to consider some Identifiable<T>
container.
Would it be considered bad practice to duplicate validations in both classes?
We do, as a general rule of thumb, consider duplication bad, although you may also be justified if you want to invoke the rule of three. You should also ask yourself if the duplication is only accidental, or if there's a systematic reason that the code is duplicated. If the later, that is, if you're always going to have to edit both files when rules change, you should consider addressing the duplication.
It may help, then, when you realize that validation is really a parsing problem. Once you realize that, you should also understand that validation is format-specific, and should only be applied at application boundaries. Once a particular piece of input has been validated, it should have been translated into a stronger representation that guarantees that the data is valid (see the above three-part articles series for examples).
With all that said, one begins to understand why ASP.NET's attribute-based model isn't suitable for the problem.
In the end, I'm afraid that the answer to questions such as the OP is mu, in the Pirsig/Hofstadter sense. One has to dig deeper and first examine why there are two, almost identical, classes in the first place. Maybe there shouldn't be.