2015-10-27 87 views
0

我正在嘗試使用MVC模式註冊新用戶並將數據保存到實體框架中;事情是,我想如下(代碼寫在模型)比較輸入的密碼和散列密碼,驗證錯誤C#MVC

[Required(ErrorMessage = "Enter Password!")] 
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 
[DataType(DataType.Password)] 
public string tPassword { get; set; } 

[DataType(DataType.Password)] 
[Compare("tPassword", ErrorMessage = "The password and confirmation password does not match.")] 
public string Confirmpassword { get; set; } 

下一個步驟是散列密碼,並將其保存比較輸入的密碼(我創建了一個名爲Security的新類以下的方法,以及其它方法來驗證密碼),以下是代碼:

public static void HashAndSavePassword(string password, RegisterTable usr) 
{ 
    var v = new Rfc2898DeriveBytes(password, 16, 3987); 
    usr.tPassword = Convert.ToBase64String(v.GetBytes(25), Base64FormattingOptions.None); 
    usr.Salt = Convert.ToBase64String(v.Salt, Base64FormattingOptions.None); 
} 

然後,在我用以下來調用負責密碼散列的方法,然後保存用戶數據到實體框架控制器:

public ActionResult Register(RegisterTable user) 
{ 
    if (ModelState.IsValid) 
    { 
     // To check if username already exist 
     var searchUserName = db.RegisterTables.Where(x => x.tUserName.Equals(user.tUserName)).FirstOrDefault(); 

     if (searchUserName == null) 
     { 
      Security.HashAndSavePassword(user.tPassword, user); 

      db.RegisterTables.Add(user); 
      db.SaveChanges(); 
      ModelState.Clear(); 
      return RedirectToAction("Login"); 
     } 
     else ModelState.AddModelError("", "User is already Registred.");    
    } 

    return View(user); 
} 

問題是,當我運行代碼,我收到以下錯誤:

enter image description here

但代碼將正常工作,如果我刪除這一行:

[Compare("tPassword", ErrorMessage = "The password and confirmation password does not match.")] 

誰能解釋對我來說爲什麼會發生這種情況以及如何解決這個問題?

回答

1

你ValidateOnSaveEnabled設置爲true你的DbContext

context.Configuration.ValidateOnSaveEnabled = true; 

這意味着您的驗證將被執行兩次。首先由模型聯編程序(由MVC完成) - 這不會拋出錯誤,因爲兩個密碼都是相同的。但是,在你的HashAndSavePassword中,你有明文形式的ConfirmPassword和散列形式的tPassword。因此,當您調用保存時,EF會引發錯誤。

您可以:

  1. 關閉EF模型驗證通過ValidateOnSaveEnabled設置爲false。
  2. 在HashAndSavePassword函數中還有hash ConfirmPassword屬性(這是黑客)
  3. 在動作中使用不同的模型,然後轉換爲EF中使用的模型。 (這被稱爲)

你DB模型

public class RegisterTable 
{ 
    public int Id { get; set; } 
    public string tPassword { get; set; } 
    public string tUserName { get; set; } 
    public string Salt { get; set; } 

    ... 
} 

你的視圖模型:

public class RegisterModel 
{ 
    // put username validation rules here 
    public string UserName { get; set; } 

    [Required(ErrorMessage = "Enter Password!")] 
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 
    [DataType(DataType.Password)] 
    public string Password { get; set; } 

    [DataType(DataType.Password)] 
    [Compare("Password", ErrorMessage = "The password and confirmation password does not match.")] 
    public string Confirmpassword { get; set; } 

    ... 

    public RegisterTable Map() 
    { 
     var v = new Rfc2898DeriveBytes(this.Password, 16, 3987); 
     return new RegisterTable() 
     { 

      Salt = Convert.ToBase64String(v.Salt, Base64FormattingOptions.None), 
      tPassword = Convert.ToBase64String(v.GetBytes(25), Base64FormattingOptions.None), 
      tUserName = this.UserName 
     }; 
    } 
} 

你的動作

public ActionResult Register(RegisterModel user) 
{ 
    if (ModelState.IsValid) 
    { 
     // To check if username already exist 
     var searchUserName = db.RegisterTables.Where(x => x.tUserName.Equals(user.UserName)).FirstOrDefault(); 

     if (searchUserName == null) 
     { 
      var dbUser = user.Map(); 

      db.RegisterTables.Add(user); 
      db.SaveChanges(); 
      ModelState.Clear(); 
      return RedirectToAction("Login"); 
     } 
     else ModelState.AddModelError("", "User is already Registred."); 
    } 

    return View(user); 
} 
+0

謝謝,它的工作,但我不明白第三點,你是什麼意思將模型轉換爲EF模型,你可以提供一些更多的信息或一個很好的教程解釋它?再次感謝 – moji

+0

現在您在註冊操作中使用RegisterTable類作爲參數。這通常不是一個好主意,因爲您的數據庫模型將具有與註冊表不同的屬性集。例如:不需要在數據庫模型上有ConfirmPassword字段,因爲您不需要將其存儲在數據庫中。並且您的數據庫模型將具有不應該暴露給視圖的屬性(例如IsDeleted,DateModified等)。因此,最好有模型來描述你的視圖表單,驗證該模型,然後將其轉換爲不同的數據庫或服務模型。 – longchiwen

+0

我得到了你的觀點,謝謝......但我仍然不知道如何轉換爲DB .. – moji