如何在ASP.NET MVC 3中正确实现“确认密码”?

37

关于同一主题已经有已回答的问题,但由于它来自于'09年,我认为它已经过时了。

如何在ASP.NET MVC 3中正确实现“确认密码”?

我在网络上看到了很多选项,其中大多数使用模型中的CompareAttribute就像这样

问题是,确定密码ConfirmPassword绝对不应该在模型中,因为它不应该被持久化。

由于整个MVC 3的无障碍客户端验证都依赖于模型,而且我不想在我的模型上放置一个ConfirmPassword属性,那我该怎么办呢?

我应该注入自定义客户端验证函数吗?如果是这样..怎么做?


4
不是所有Model中的类型(或类型成员)都需要持久化。您的服务器验证呢? - oleksii
1
不仅确认密码,而且密码也不应该被持久化。Darin Dimitrov的使用ViewModel的解决方案是正确的,除了关于AutoMapper的注释。在持久化之前,您应始终对密码进行盐值处理和安全哈希处理。 - Juraj Suchár
Darin从未表示过他会持久化明文密码,他只是说他会将视图模型映射到域模型,并将其传递给存储库。我认为哈希密码的细节更正确地属于持久化代码而不是演示代码(为什么我的MVC控制器必须知道安全哈希的细节?)。 - David Hay
2个回答

97

MVC 3中整个无阻碍客户端验证都依赖于模型,我不想在我的模型上添加ConfirmPassword属性,该怎么办?

我完全同意您的看法。这就是为什么你应该使用视图模型。然后在你的视图模型(一个专门设计给定视图要求的类)上,你可以使用[Compare]属性:

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; }
}

然后让您的控制器操作采用此视图模型。

[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");
}

我没有“Compare”属性可用...我缺少了什么? - jocull
@jocull,嗯,ASP.NET MVC 3?如果您使用的是旧版本,则不会有此属性。 - Darin Dimitrov
这绝对是MVC 3...我是否错过了一个已包含的程序集? - jocull
2
@jocull,请阅读文档。程序集:System.Web.Mvc.dll。命名空间:System.Web.Mvc - Darin Dimitrov
3
在较新的C#中,最好使用[Compare(nameof(Password), ...]而不是硬编码Password属性名称。 - Mariusz Jamro
显示剩余2条评论

3

看一下MVC3应用程序的默认VS2010模板。

它包含一个名为RegisterModel(一个“视图模型”)的模型,其中包含密码和确认密码属性。验证设置在确认密码上。

因此,答案是MVC中的模型不必(通常不是)与您的业务模型相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接