38

There's already an answered question about the same subject but as it's from '09 I consider it outdated.

How to properly implement "Confirm Password" in ASP.NET MVC 3?

I'm seeing a lot of options on the Web, most of them using the CompareAttribute in the model like this one

The problem is that definitely ConfirmPassword shound't be in the model as it shouldn't be persisted.

As the whole unobstrusive client validation from MVC 3 rely on the model and I don't feel like putting a ConfirmPassword property on my model, what should I do?

Should I inject a custom client validation function? If so.. How?

3
  • 4
    Not all the types (or type members) that are in Model must be persisted. What about your server validation? Commented Jul 23, 2011 at 16:48
  • 1
    Not only ConfirmPassword, but also Password should not be persisted. Darin Dimitrov's solution with a ViewModel is correct except for the note about AutoMapper. You should always salt and secure hash password prior to persisting it. Commented Aug 15, 2012 at 9:58
  • Darin never indicated that he would persist the plaintext password, he just said that he would map the viewmodel to a domain model, and pass that to a repository. I would argue that the details of hashing a password more correctly belongs with the persistence code than in the presentation code (Why should my MVC controllers have to know the details of a secure hash?). Commented Feb 20, 2014 at 18:46

2 Answers 2

99

As the whole unobstrusive client validation from MVC 3 rely on the model and I don't feel like putting a ConfirmPassword property on my model, what should I do?

A completely agree with you. That's why you should use view models. Then on your view model (a class specifically designed for the requirements of the given view) you could use the [Compare] attribute:

public class RegisterViewModel
{
    [Required]
    public string Username { get; set; }

    [Required]
    public string Password { get; set; }

    [Compare("Password", ErrorMessage = "Confirm password doesn't match, Type again !")]
    public string ConfirmPassword { get; set; }
}

and then have your controller action take this view model

[HttpPost]
public ActionResult Register(RegisterViewModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    // TODO: Map the view model to a domain model and pass to a repository
    // Personally I use and like AutoMapper very much (http://automapper.codeplex.com)

    return RedirectToAction("Success");
}
Sign up to request clarification or add additional context in comments.

7 Comments

I don't have a Compare attribute available... what am I missing?
@jocull, erm, ASP.NET MVC 3? If you are using an older version you won't have this attribute.
It's definitely MVC 3... am I missing an included assembly?
@jocull, read the documentation. Assembly: System.Web.Mvc.dll. Namespace: System.Web.Mvc.
In newer C# its better use [Compare(nameof(Password), ...] instead of hardcoding Password property name.
|
3

Take a look at the default VS2010 template for a MVC3 app.

It contains a RegisterModel (a 'ViewModel') that contains the Password and ConfirmPassword properties. The validation is set on the ConfirmPassword.

So the answer is that the Models in MVC don't have to be (usually aren't) the same as your business Models.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.