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

时间:2011-07-28 14:02:54

标签: .net asp.net-mvc asp.net-mvc-3 data-annotations

我的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创建自定义验证器更好的解决方案,您怎么看?

3 个答案:

答案 0 :(得分:3)

为什么不拨打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项目模板中完成的。除非您想要客户端验证,否则我不确定检查密码是否正确的目的是什么,然后调用更改密码。这只是对数据库的额外调用,这似乎是不必要的。

答案 1 :(得分:2)

你可以使用 [远程]注释。

它将对某个控制器中的方法进行ajax调用。在那里,您可以访问数据库或进行其他一些验证。

[Remote("CheckPassword","YourController", ErrorMessage = "Wrong currentpassword")]
[Required]
public string CurrentPassword { get; set; }


public ActionResult CheckPassword(String Password)
        {
            if (YourRepository.CheckIfPassIsCorrect(Password))
            {
                return Json(false, JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json(true, JsonRequestBehavior.AllowGet);
            }
        }

另一种解决方案

提交给控制器时。 做这样的事情:

  if(!YourRepository.CheckIfPassIsCorrect(YourViewModel.CurrentPassword)
    {
    ModelState.AddModelError("CurrentPassword", "Your current password isn't correct");

//Return to your view
    }

答案 2 :(得分:0)

我的解决方案是构建一个与DataAnnotations一起使用的自定义验证,这里是代码:

public class CurrentPasswordAttribute : ValidationAttribute
{
    AuthenticationService authenticationService = new AuthenticationService();

    public override bool IsValid(object value)
    {
        string strValue = value as string;

        if (!string.IsNullOrEmpty(strValue))
        {
            return authenticationService.ValidateUser(HttpContext.Current.User.Identity.Name, strValue);
        }

        return false;
    }

    public override string FormatErrorMessage(string name)
    {
        return String.Format(CultureInfo.CurrentCulture, base.ErrorMessageString, name);
    }
}

在我的ViewModel中:

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

    public string NewPassword { get; set; }

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

感谢。