2011-06-28 19 views
0

ので、 iはフィールドをたくさん持っている「ユーザー」モデルを持っていますが、次は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を持っている必要があるので、コピー貼り付けはできません。バックグラウンド監査がたくさんあるので、Userエンティティ全体を壊してしまいます。プロファイルが編集/作成されるたびにパスワードを検証する必要があります。

編集: みなさんは混乱してしまいます。基本的には、私は確認パスワードに必要な複数の検証を持っています。これはデータアノテーションでは処理できません。確かにconfirmpassword viewmodelです。この検証はUserモデルに適用したいが、 "ConfirmPassword"フィールドを追加する必要はありません。データベース上に別のフィールドは必要ありません。私の質問は、ビューのPOSTとパスワードフィールドがその要件を満たさないときはいつも、私がconfirmapasswordから持っているバリデーションを強制するのですか?

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検証と論理検証は混同されるべきではありません。それは、同じことであっても論理の中でもう一度やり直す価値があります。基本的には、検証を実行するのはEntityオブジェクトの責任ではありません。それはエンティティのためにそれをするいくつかのサービス層クラスかもしれません。そして、おそらく、その時点で例外をスローすることができます。それは、UIとロジックで全く異なる方法で処理されます。

0

障害をチェックするためのViewModelには、IsValidと組み合わせる

使用データ注釈を「プロファイルを作成/編集されるたびに、私はちょうどパスワードを検証する必要があります」。モデルをビューモデルにマッピングする限り、デコレータパターンを使用するだけです。

使用System.ComponentModel.DataAnnotations(彼らもあなたが使用できる正規表現のバリデータを持っている) パスワードがポリシーと照合して検証されると、MD5ハッシュに変換し、他のすべてが失敗した場合、パスワード値 、それをしませ保存別のUserValidationクラスを作成し、View ModelとModelの間でロジックを共有することには何も問題ありません。それらは両方とも妥当性を判断するために同じメソッドを呼び出す(コードを減らす)。

1

[OK]を、私はまだあなたがモデルエンティティにビューモデルを接続することによって何を意味するかについて少しです...私はあなたが望むものは、実際のユーザーからのパスワードがビューモデルに渡されたパスワードと一致するかどうかを確認することです。

私は個人的にビューモデル自体ではなく、コントローラでこれを行い、パスワードが間違っている場合は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); 
} 
関連する問題