.net - 验证使用.Net MVC 3在ViewModel中更改密码的当前密码的最佳实践?

原文 标签 .net asp.net-mvc asp.net-mvc-3 data-annotations

Best practice to validate Current Password for Change Password in ViewModel with .Net MVC 3?

My ViewModel:

public class EditViewModel
{
    [Required]
    public string CurrentPassword { get; set; }

    public string NewPassword { get; set; }

    [Compare("NewPassword")]
    public string ConfirmNewPassword { get; set; }
}

I'm trying to validate CurrentPassword field. I thought about creating a Custom Validator Attribute that connect to my database(for retrieve current password) for use with DataAnnotations.

There is a better idea?

Update:

I know I can doing this validation in my controller, but I'm trying to avoid this validation logic in my controller. Just for beauty of my code/architecture.

I have not seen a better solution than create a Custom Validator for use with DataAnnotations, what do you think?

Answer

Why not just make a call to Membership.ChangePassword? If it fails then you can add an error to the ModelState:

    [Authorize]
    [HttpPost]
    public ActionResult ChangePassword(ChangePasswordModel model)
    {
        if (ModelState.IsValid)
        {

            // ChangePassword will throw an exception rather
            // than return false in certain failure scenarios.
            bool changePasswordSucceeded;
            try
            {
                MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
                changePasswordSucceeded = currentUser.ChangePassword(model.OldPassword, model.NewPassword);
            }
            catch (Exception)
            {
                changePasswordSucceeded = false;
            }

            if (changePasswordSucceeded)
            {
                return RedirectToAction("ChangePasswordSuccess");
            }
            else
            {
                ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

This is all done in the default Internet project template by the way. Unless you are wanting client side validation I'm not sure what the purpose of checking to see if their password is correct, then calling Change Password. It would just be an extra call to the database which seems unnecessary.

翻译

我的ViewModel:

public class EditViewModel
{
    [Required]
    public string CurrentPassword { get; set; }

    public string NewPassword { get; set; }

    [Compare("NewPassword")]
    public string ConfirmNewPassword { get; set; }
}


我正在尝试验证CurrentPassword字段。我考虑过创建一个自定义验证器属性,该属性连接到我的数据库(用于检索当前密码)以与DataAnnotations一起使用。

有更好的主意吗?

更新:

我知道我可以在控制器中执行此验证,但是我正在尝试避免在控制器中执行此验证逻辑。仅出于我的代码/体系结构的美。

没有比创建用于DataAnnotations的自定义验证器更好的解决方案了,您认为呢?
最佳答案
为什么不打电话给Membership.ChangePassword?如果失败,则可以向ModelState添加错误:

    [Authorize]
    [HttpPost]
    public ActionResult ChangePassword(ChangePasswordModel model)
    {
        if (ModelState.IsValid)
        {

            // ChangePassword will throw an exception rather
            // than return false in certain failure scenarios.
            bool changePasswordSucceeded;
            try
            {
                MembershipUser currentUser = Membership.GetUser(User.Identity.Name, true /* userIsOnline */);
                changePasswordSucceeded = currentUser.ChangePassword(model.OldPassword, model.NewPassword);
            }
            catch (Exception)
            {
                changePasswordSucceeded = false;
            }

            if (changePasswordSucceeded)
            {
                return RedirectToAction("ChangePasswordSuccess");
            }
            else
            {
                ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }


顺便说一下,这都是在默认的Internet项目模板中完成的。除非您要进行客户端验证,否则我不确定检查密码是否正确然后调用更改密码的目的。这只是对数据库的额外调用,这似乎是不必要的。
相关推荐

c# - 我们还是应该使用服务器端网格还是Javascript网格?

c# - 使用属性在代码优先EF 4.1中配置TPH Discriminator列

.net - .Net垃圾回收的速度慢于创建/删除对象的速度,该怎么办?

c# - 在.NET中使进程窗口可见/不可见

.net - 使用MVVM设计模式将WCF服务用作WPF应用程序中的模型

c# - 可以使用HTTP跟踪连接吗?

c# - C#中的奇数移位

.net - 使用反射查找所有公共虚拟方法并提供覆盖

c# - C#控制台应用程序用户可编辑的设置

.net - ASP:Kentico最终标记中的文字印刷