繁体   English   中英

mvc model 和视图模型?

[英]mvc model and viewmodel?

所以,我有一个“用户”model,它有很多字段,但以下是impt:


public int Id {get;set;}
public string Username { get; set; }
public string Pwd { get; set; }

我有一个视图 model 验证我在不同的 controller 上使用的密码:

public class ConfirmPassword : IValidatableObject
{
    [Required]
    public string Password { get; set; }
    [Required(ErrorMessage="Confirm Password field is required.")]
    public string ConfirmPwd { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        string regex1 = @"^.{8,10}$";                   // 8 - 10 characters

        Match requirement1 = Regex.Match(Password, regex1);

        if (Password != ConfirmPwd)
            yield return new ValidationResult("Password and Confirm Password is not identical.");

        if (!requirement1.Success)
            yield return new ValidationResult("Password must be between 8 and 10 characters.");


    }
}

有没有办法可以将视图 model 连接到我的 model 实体? 或者只是复制粘贴代码我唯一的选择? 我不能复制粘贴,因为代码需要有一个 IValidateObject ,这会弄乱整个用户实体,因为有大量的后台审计正在发生。我只需要在编辑/创建配置文件时验证密码。

编辑:很抱歉,如果每个人都感到困惑。 基本上,我需要对数据注释无法处理的确认密码进行多次验证,因此确认密码视图模型。 我想将此验证应用于用户 model 但不添加“确认密码”字段。 因为我不需要数据库上的另一个字段。 我的问题是,当视图 POST 和密码字段不符合其要求时,如何强制我从确认密码中获得的验证触发?

namespace
{
    public class User 
    {
public int Id {get;set;}
public string Username { get; set; }
public string Pwd { get; set; }

    }
}


namespace
{
    public class ConfirmPassword : IValidatableObject
    {
        [Required]
        public string Password { get; set; }
        [Required(ErrorMessage="Confirm Password field is required.")]
        public string ConfirmPwd { get; set; }

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            string regex1 = @"^.{8,10}$";                   // 8 - 10 characters
            string regex2 = @"(?:.*?[A-Z]){1}";             // 1 uppercase
            string regex3 = "";             // 1 lowercase
            string regex4 = "";                // 1 numeric

            Match requirement1 = Regex.Match(Password, regex1);
            Match requirement2 = Regex.Match(Password, regex2);
            Match requirement3 = Regex.Match(Password, regex3);
            Match requirement4 = Regex.Match(Password, regex4);

            if (Password != ConfirmPwd)
                yield return new ValidationResult("Password and Confirm Password is not identical.");

            if (!requirement1.Success)
                yield return new ValidationResult("Password must be between 8 and 10 characters.");

            if (!requirement2.Success)
                yield return new ValidationResult("Password must contain at least 1 uppercase letter.");

            if (!requirement3.Success)
                yield return new ValidationResult("Password must contain at least 1 lowercase letter.");

            if (!requirement4.Success)
                yield return new ValidationResult("Password must contain at least 1 numeric character.");

        }
    }
} 

您可以使用视图 model 中的装饰器模式来做您喜欢的事情。 您还可以使用System.ComponentModel.DataAnnotations命名空间属性为您完成所有验证。

public class ConfirmPassword 
{
    User model;

    [Required]
    public string Username 
    { 
        get { return this.model.Username; } 
        set { this.model.Username = value; } 
    }
    [Required]
    [DataType(DataType.Password)]
    public string Password 
    { 
        get { return this.model.Pwd; } 
        set { this.model.Pwd = value; } 
    }

    [Required(ErrorMessage = "Confirm Password field is required.")]
    [Compare("NewPassword", 
       ErrorMessage = "The new password and confirmation password do not match.")]
    [RegularExpression(@"^.{8,10}$")]
    [DataType(DataType.Password)]
    public string ConfirmPwd { get; set; }

    public ConfirmPassword()
    {
        this.model = new User();
    }

    public ConfirmPassword(User model)
    {
        this.model = model;
    }

}

好的,我仍然有点不确定将视图 model 连接到 model 实体的意思......我想你现在想要检查来自实际用户的密码是否与传递给视图 Z20F35E630DAF44DFAC4ZC3F6 的密码相匹配。

我个人不会在视图 model 本身中执行此操作,而是在 controller 中执行此操作,并且如果密码不正确会添加 ModelState.AddError。

如果您使用客户端验证,则可以在服务器或客户端进行正常的输入验证,但您无法检查密码客户端,因此它必须 go 到服务器。

public LoginViewModel()
{
  [Required]
  public string LoginId {get; set;}

  [DataType(DataType.Password)]
  public string Password {get; set;}

  [DataType(DataType.Password)]
  public string ConfirmPassword {get; set;}

 // this validation is not db related and can be done client side...
 public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        string regex1 = @"^.{8,10}$";                   // 8 - 10 characters

        Match requirement1 = Regex.Match(Password, regex1);

        if (Password != ConfirmPwd)
            yield return new ValidationResult("Password and Confirm Password is not identical.");

        if (!requirement1.Success)
            yield return new ValidationResult("Password must be between 8 and 10 characters.");


    }

}

[HttpGet]
public ActionResult Login()
{
   var model = new LoginViewModel();

   return View("Login",model);
}

[HttpPost]
public ActionResult Login(LoginViewModel model)
{

   var user = GetUserFromRepositoryByUsername(model.username);

   if(user != null)
    {
      if(user.password == model.Password)
      {
        RedirectToAction("YouLoggedInYay!");
      }
    }

    // if we made it this far, the user didn't exist or the password was wrong.
    // Highlight the username field red and add a validation error message.
    ModelState.AddError("Username","Your credentials were invalid punk!");

   return View("Login",model);
}

我会在您的 ViewModel 中包含一个 userId 或将其添加到 URL 上,以便 controller 可以获取它。

验证密码组合后,您可以使用 ID 检索相关用户并使用新密码对其进行更新。 您可以在新密码发布操作中执行此操作。

顺便说一句,您可能想要匹配旧密码。

据我所知,您的 UI 验证和逻辑验证不应该混为一谈。 即使是同一件事,也值得在逻辑中重新做一遍。 基本上,实体 object 不负责进行验证。 可能是某个服务层 class 为实体执行此操作。 那时你可能会抛出一个异常。所以它在 UI 和逻辑中以完全不同的方式处理。

“每当编辑/创建配置文件时,我只需要验证密码”

在 ViewModel 上使用结合 IsValid 的数据注释来检查故障。 至于将 Model 映射到视图 Model 只需使用装饰器模式。

使用 System.ComponentModel.DataAnnotations (他们甚至有一个您可以使用的正则表达式验证器)一旦根据策略验证密码,将它们转换为 MD5 hash 并存储它,而不是密码值如果所有其他方法都失败,那么创建没有任何问题一个单独的 UserValidation Class 并在视图 Model 和 Model 之间共享逻辑,例如它们都调用相同的方法来确定有效性(减少代码)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM