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"})
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.