DataValidation Model / ViewModel / Entity Framework Code First

I am developing a new site with ASP.NET MVC 4 (Beta), VS 11 (beta), EF 5 (beta), but this question is suitable for released versions of ASP.NET MVC 3, VS 2010, EF 4, too.

First step: I use the Entity Framework Code First approach, for example, I have the following user model:

public class User { [Key] public int UserId {get;set;} public String LoginName { get; set; } public String Password { get; set; } } 

Now for registration I need another model, registration model:

 public class Registration { public String LoginName { get; set; } public String Password { get; set; } public String PasswordConfirm { get; set; } } 

This is where my problems begin: Where should I put my DataValidation annotations? For example, the password must be at least 10 characters, and PasswordConfirmed must match the password, etc. Do I have to write this on every model that could do something with a password (I also want to have a ChangePassword model)

Another thing is how to deal with the controller. When I show my registration ViewModel and everything is fine, do I create a user model and assign variables from Registration ViewModel to it?

Sometimes I have many properties that go to the database but are not displayed to the user (foreign keys, calculated values, etc.).

How to think about SUCHA, I do not want to repeat myself.

What is the best practice for this?

To be clear: annotations are not needed. If there are more effective verification methods, I will be glad if you show them.

+4
source share
2 answers

I cannot objectively say what is “best practice”, but here, as I see it. If you are attached to a view model, check the view model, so:

 public class Registration { public String LoginName { get; set; } [Required] [StringLength(50, MinimumLength=10)] public String Password { get; set; } [Required] [StringLength(50, MinimumLength=10)] public String PasswordConfirm { get; set; } } 

You can either perform a manual check in the controller, check the POST if the password and confirmation match, if you do not add an entry to the ModelState (but this can lead to code repeating and a little cumbersome) OR use the nice IValidatableObject interface on the model:

 public class Registration : IValidatableObject { public String LoginName { get; set; } [Required] [StringLength(50, MinimumLength=10)] public String Password { get; set; } [Required] [StringLength(50, MinimumLength=10)] public String PasswordConfirm { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext context) { if(Password != PasswordConfirm) yield return new ValidationResult("Confirmation doesn't match", new[] {"PasswordConfirm"}) //etc. } } 

Now with this, when your model is bound after POST , the check is done by a simple call to ModelState.IsValid , and if it is invalid, it returns a list of errors, including your custom errors.

Now, of course, you can put DataAnnotations on the DB model as an additional measure, just “in case”, to avoid exceptions from row truncation, etc. if you somehow forgot and tried to push a longer row into the database anyway

As for the display, yes, after you have confirmed your model, at the end of the POST action, you usually map the model properties to a new User instance (when added to the database) or to an existing one for updating. You can use AutoMapper or write a naive cartographer yourself using reflection - this is a relatively simple task, but it’s better to leave it as a standalone exercise, it makes no sense to reinvent the wheel.

+2
source

You should create your objects only at the domain level. But when you need some DataValidation annotations for your entity, you can use MvcExtensions . And if you have compound or nested objects, and you want to get them as smoothed objects, you should use automapper . This will be the best practice for you!

+1
source

Source: https://habr.com/ru/post/1415516/


All Articles