2011-06-24 78 views
12

我有單獨的模型和視圖模型類。其中viewmodel類只進行UI級別驗證(請參閱:Validation: Model or ViewModel)。驗證Model和ViewModel的最佳實踐

我可以在控制器中驗證模型(vewmodel)是否有效。

問: 如何驗證模型(帶有數據註釋的主要實體)。

我沒有開發使用模型對象的視圖模型。只需複製屬性並添加該特定視圖中可能需要的所有屬性即可。

//Model Class 
public class User 
{ 
    [Required] 
    public string Email {get; set;} 

    [Required] 
    public DateTime Created {get; set;} 
} 

//ViewModel Class 
public class UserViewModel 
{ 
    [Required] 
    public string Email {get; set;} 

    [Required] 
    public string LivesIn {get; set;} 
} 

//Post action 
public ActionResult(UserViewModel uvm) 
{ 
    if(ModelState.IsValid) 
     //means user entered data correctly and is validated 

    User u = new User() {Email = uvm.Email, Created = DateTime.Now}; 
    //How do I validate "u"? 

    return View(); 
} 

應該做這樣的事情:

var results = new List<ValidationResult>(); 
var context = new ValidationContext(u, null, null); 
var r = Validator.TryValidateObject(u, context, results); 

我在想什麼基類是添加(業務實體)此驗證的技術,並驗證它,當我從映射視圖模型類到商業實體。

有什麼建議嗎?

回答

9

1)在從用戶檢索信息的模型上使用流暢的驗證。它更靈活,然後數據註釋,更容易測試。

2)您可能需要查看automapper,通過使用automapper,您不必編寫x.name = y.name

3)對於您的數據庫模型,我會堅持數據註釋。下面

一切都基於新的信息

首先,所有你應該把驗證兩個位置,就像你現在所做的實際模型驗證,這是我會怎麼做。 免責聲明:這不是一個完美的方式

首先,所有更新UserViewModel

public class UserViewModel 
    { 
     [Required()] 
     [RegularExpression(@"^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9][email protected]((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$")] 
     public String Email { get; set; } 
    } 

然後更新行動方法

 // Post action 
     [HttpPost] 
     public ActionResult register (UserViewModel uvm) 
     { 
      // This validates the UserViewModel 
      if (ModelState.IsValid) 
      { 

       try 
       { 
        // You should delegate this task to a service but to keep it simple we do it here 
        User u = new User() { Email = uvm.Email, Created = DateTime.Now }; 
        RedirectToAction("Index"); // On success you go to other page right? 
       } 
       catch (Exception x) 
       { 
        ModelState.AddModelError("RegistrationError", x); // Replace x with your error message 
       } 

      }  

      // Return your UserViewModel to the view if something happened    
      return View(uvm); 
     } 

現在的用戶模型,可以得到棘手和你有很多可能的解決方案。我想出了一個解決方案(可能不是最好的)如下:

public class User 
    { 
     private string email; 
     private DateTime created; 

     public string Email 
     { 
      get 
      { 
       return email; 
      } 
      set 
      { 
       email = ValidateEmail(value); 
      } 
     } 

     private string ValidateEmail(string value) 
     { 
      if (!validEmail(value)) 
       throw new NotSupportedException("Not a valid email address");  

      return value; 
     } 

     private bool validEmail(string value) 
     { 
      return Regex.IsMatch(value, @"^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9][email protected]((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$"); 
     } 

末一些單元測試,以檢查自己的代碼:

[TestClass()] 
    public class UserTest 
    { 

     /// <summary> 
     /// If the email is valid it is stored in the private container 
     /// </summary> 
     [TestMethod()] 
     public void UserEmailGetsValidated() 
     { 
      User x = new User(); 
      x.Email = "[email protected]"; 
      Assert.AreEqual("[email protected]", x.Email); 
     } 

     /// <summary> 
     /// If the email is invalid it is not stored and an error is thrown in this application 
     /// </summary> 
     [TestMethod()] 
     [ExpectedException(typeof(NotSupportedException))] 
     public void UserEmailPropertyThrowsErrorWhenInvalidEmail()  
     { 
      User x = new User(); 
      x.Email = "blah blah blah"; 
      Assert.AreNotEqual("blah blah blah", x.Email); 
     } 


     /// <summary> 
     /// Clears an assumption that on object creation the email is validated when its set 
     /// </summary> 
     [TestMethod()] 
     public void UserGetsValidatedOnConstructionOfObject() 
     { 
      User x = new User() { Email = "[email protected]" }; 
      x.Email = "[email protected]"; 
      Assert.AreEqual("[email protected]", x.Email); 
     } 
    } 
+0

珠三角@Serghei其實我想知道我該怎麼辦驗證模型類(不綁定查看)。保持我的視圖具有來自不同模型類(在ViewModel類中)的屬性,以滿足特定視圖的所有需求。 – Yahya

+0

@Yahya你能舉一個例子嗎?指出您應該在哪裏以及如何進行驗證會更容易。 – David

+0

prd我已經在原始問題中爲您添加了示例代碼。我希望現在有道理。 – Yahya