2011-06-28 131 views
0

所以, 我有了很多領域的「用戶」模式,但以下是IMPT的:mvc模型和viewmodel?


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

和我有驗證,我在使用口令視圖模型不同的控制器:

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."); 


    } 
} 

有沒有一種方法可以將視圖模型連接到我的模型實體?或者只是複製粘貼代碼我的唯一選擇?我不能複製粘貼,因爲代碼需要有一個IValidateObject,這將會弄亂整個用戶實體,因爲有大量的後臺審計發生。我只需要在編輯/創建配置文件時驗證密碼。

編輯: 很抱歉,如果每個人都感到困惑。基本上,我有多個驗證,我需要確認無法通過dataannotations處理的密碼,請使用confirmpassword視圖模型。我希望將這種驗證應用到用戶模型上,但不在其中添加「ConfirmPassword」字段。因爲我不需要數據庫上的另一個字段。我的問題是,如何強制驗證密碼中的驗證觸發視圖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."); 

     } 
    } 
} 
+2

爲什麼你不使用'StringLengthAttribute' –

+0

好,這不是我唯一的驗證。我只是把它縮短了。還有4個使用正則表達式。 – gdubs

+0

如果您對情況有任何控制權,則應避免使用密碼長度的設置上限。告訴外部世界密碼是8-10個字符還告訴黑客在進行暴力攻擊時需要使用多少個字符。 –

回答

0

我會在您的ViewModel中包含一個userId或將其添加到URL中,以便控制器可以將其提取出來。

驗證密碼組合後,您使用Id檢索相關用戶並使用新密碼進行更新。您可以在您的新密碼發佈後執行此操作。

你可能想要匹配舊密碼btw。

1

您可以在視圖模型中使用裝飾器模式來做你喜歡的事情。您還可以使用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; 
    } 

} 
0

從我相信你的UI驗證和邏輯驗證不應該混在一起。即使它是相同的東西,在邏輯中再次重申也是值得的。基本上,實體對象不承擔驗證的責任。它可能是一些服務層類,它爲實體。而且你可能會在這個時候拋出一個異常。所以它在UI和邏輯中以完全不同的方式處理。

0

「我只是需要驗證每當配置文件編輯密碼/創建」用的IsValid在視圖模型相結合,檢查故障

使用數據的註釋。至於將模型映射到視圖模型只需使用裝飾器模式。

使用System.ComponentModel.DataAnnotations(他們甚至可以使用正則表達式驗證) 一旦密碼是抵禦政策查實,將其轉換爲一個MD5哈希和商店,而不是密碼值 如果一切都失敗在視圖模型和模型之間創建單獨的UserValidation類和共享邏輯沒有任何問題,例如,他們都調用相同的方法來確定有效性(減少代碼)。

1

好吧,我還是有點如果你的意思是將視圖模型連接到模型實體...我想你想要的是現在檢查來自實際用戶的密碼是否與傳遞給視圖模型的密碼匹配。

我個人不會這樣做在視圖模型本身,而是在控制器中,如果密碼不正確,會添加一個ModelState.AddError。

如果您正在使用客戶端驗證,但是您無法檢查密碼客戶端,那麼正常輸入驗證可能發生在服務器或客戶端,因此它必須轉到服務器。

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