2011-06-24 59 views
12

Tôi có các lớp mô hình và chế độ xem riêng biệt. Trường hợp các lớp viewmodel chỉ thực hiện xác thực mức UI (tham khảo: Validation: Model or ViewModel).Thực hành xác thực tốt nhất cho Mô hình và ViewModel

Tôi có thể xác minh về tác vụ đăng trong bộ điều khiển mô hình (vewmodel) hợp lệ.

Yêu cầu: Làm cách nào để xác thực mô hình (thực thể chính có chú thích dữ liệu).

Tôi không phát triển chế độ xem mô hình bằng cách sử dụng đối tượng mô hình. Chỉ cần sao chép các thuộc tính và thêm tất cả các thuộc tính có thể được yêu cầu trong chế độ xem cụ thể đó.

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

nên làm điều gì đó như thế này:

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

Những gì tôi đang nghĩ sẽ bổ sung kỹ thuật xác nhận này trong lớp cơ sở (của đơn vị kinh doanh), và xác minh điều đó khi tôi đang lập bản đồ từ lớp viewmodel đến thực thể nghiệp vụ.

Mọi đề xuất?

Trả lời

9

1) Sử dụng xác thực thông thạo trên mô hình để truy xuất thông tin từ người dùng. nó linh hoạt hơn sau đó chú thích dữ liệu và dễ dàng hơn để kiểm tra.

2) Bạn có thể muốn xem xét tự động hóa, bằng cách sử dụng automapper bạn không phải viết x.name = y.name.

3) Đối với mô hình cơ sở dữ liệu của bạn, tôi sẽ dính vào chú thích dữ liệu.

Tất cả mọi thứ dưới đây dựa trên các thông tin mới

Đầu tiên và tất cả các bạn nên đặt xác nhận trên cả hai vị trí như bạn đã làm ngay bây giờ để xác nhận mô hình thực tế đây là cách tôi sẽ làm điều đó. Disclaimer: đây không phải là cách hoàn hảo

Đầu tiên và tất cả các bản cập nhật các 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; } 
    } 

Sau đó cập nhật các phương pháp hành động để

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

Bây giờ cho các mô hình sử dụng nó được khéo léo và bạn có nhiều giải pháp khả thi.Các giải pháp tôi đã đưa ra (có lẽ không phải là tốt nhất) như sau:

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

cuối một số bài kiểm tra đơn vị để kiểm tra mã của riêng tôi:

[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

prd @Serghei Tôi thực sự muốn biết làm cách nào để xác nhận lớp mô hình (mà không bị ràng buộc để xem). Lưu ý rằng các khung nhìn của tôi có các thuộc tính từ các lớp mô hình khác nhau (trong một lớp ViewModel) để đáp ứng tất cả các yêu cầu trên Chế độ xem cụ thể đó. – Yahya

+0

@Yahya Bạn có thể đăng một ví dụ không? nó sẽ dễ dàng hơn để chỉ ra nơi bạn nên, và làm thế nào, để làm xác nhận. – David

+0

prd Tôi đã thêm mã mẫu trong câu hỏi gốc cho bạn. Tôi hy vọng nó có ý nghĩa bây giờ. – Yahya

Các vấn đề liên quan