2012-12-26 21 views
5

Tôi hiện đang có một thiết lập ViewModel như vậy:Members Models Nested

public class OurViewModel 
    { 
     public OurViewModel() { } 

     [Required] 
     public int LeadID { get; set; } 
     [Required] 
     public int Rate { get; set; } 
     [Required] 
     public bool DepositRequired { get; set; } 
     [RequiredIfOtherPropertyIsTrue("DepositRequired")] 
     public BankInfo { get; set; } 
    } 

... trong trường hợp này, "RequiredIfOtherPropertyIsTrue" là một validator mà không khá nhiều những gì nó nói: kiểm tra xem nếu bất động sản khác là đúng (trong trường hợp này, boolean của chúng tôi cho thấy có hay không đặt cọc là cần thiết), và BankInfo là một mô hình mà trông giống như sau:

public class BankInfo 
{ 
    public enum AccountTypeEnum 
    { 
     CHECKING, 
     SAVINGS 
    } 

    public BankAccountInfo() { } 

    [DisplayName("Account Number")] 
    [Required(ErrorMessage = "You must provide a valid bank account number")] 
    public String AccountNumber { get; set; } 

    [DisplayName("Bank Routing Number")] 
    [Required(ErrorMessage = "You must provide a valid routing number")] 
    [StringLength(9, MinimumLength = 9, ErrorMessage = "Your bank routing number must be exactly 9 digits")] 
    public String ABANumber { get; set; } 

    [DisplayName("Bank Account Type")] 
    [Required] 
    public AccountTypeEnum AccountType { get; set; } 

    [DisplayName("Name on Bank Account")] 
    [Required(ErrorMessage = "You must provide the name on your bank account")] 
    public String AccountName { get; set; } 
} 

Bây giờ, trong ViewModel của chúng tôi, chúng tôi có một hộp kiểm ràng buộc để DepositRequired của chúng tôi boolean và một EditorFor w/một mẫu tùy chỉnh cho BankInfo. Khi gửi, chúng tôi gặp sự cố khi tìm hiểu cách vô hiệu hóa xác thực trên BankInfo IF không yêu cầu bởi mô hình (ví dụ: ngay cả khi chúng tôi không yêu cầu thuộc tính trên ViewModel, nó vẫn kích hoạt val trên BankInfo và do đó, không thành công khốn khổ trên bất kỳ bài đăng nào). Có cách nào tiêu chuẩn để xử lý w/xác nhận mô hình lồng nhau trên ViewModel ràng buộc?

+0

Là một lưu ý, ngay cả nếu chúng ta rip validator tùy chỉnh của chúng tôi tắt của BankInfo và để nó như một tài sản undecorated trên ViewModel, xác nhận BankInfo vẫn đá tại ngay cả khi isn bất động sản' không bị ràng buộc từ việc gửi biểu mẫu. – antinescience

+0

Lý do cú pháp xác nhận của BankInfo là bởi vì trình kết nối mô hình mặc định sẽ ràng buộc hoàn toàn và xác thực các con của mô hình trước khi nó có thể hoàn thành ràng buộc và xác nhận hợp lệ mô hình vùng chứa. Tôi không chắc chắn có một workaround cho điều này bên ngoài làm một chất kết dính mô hình tùy chỉnh. – rossisdead

Trả lời

5

Thật không may, với việc xây dựng trong xác nhận, bạn sẽ phải sử dụng

ModelState.Remove("BankInfo"); 

có điều kiện bỏ qua bất kỳ thất bại xác nhận về đối tượng đó.

Nếu sử dụng FluentValidation là một lựa chọn, bạn có thể làm một cái gì đó như thế này trong OurViewModelValidator của bạn:

RuleFor(ourViewModel=> ourViewModel.BankInfo).SetValidator(new BankInfoValidator()).When(ourViewModel=> ourViewModel.DepositRequired); 

và sau đó để xác nhận BankInfoValidator xử lý của đối tượng đó.

Cái gì như:

public class BankInfoValidator : AbstractValidator<BankInfo> 
{ 
    public BankAccountInfoValidator() 
    { 
     RuleFor(bank => bank.AccountName).NotEmpty().WithMessage("You must provide a name for your bank account."); 
     RuleFor(bank => bank.AccountNumber).NotEmpty().WithMessage("You must provide an account number for your bank information."); 
     RuleFor(bank => bank.AccountType).NotEmpty().WithMessage("You must select what kind of bank account you're entering information for (checking, savings)."); 
     RuleFor(bank => bank.ABANumber).NotEmpty().WithMessage("You must provide a routing number for your bank information."); 
     RuleFor(bank => bank.ABANumber).Must(BeOnlyDigits).WithMessage("Your routing number can only contain numeric characters, 0-9."); 
     RuleFor(bank => bank.AccountNumber).Must(BeOnlyDigits).WithMessage("Your account number can only contain numeric characters, 0-9."); 
    } 

    private bool BeOnlyDigits(string digitString) 
    { 
     int result; 
     return int.TryParse(digitString, out result); 
    } 
+0

+1 cho [FluentValidation] (http://fluentvalidation.codeplex.com/) - tìm thấy nó từ một loạt các ánh nhìn lướt qua khác tại các bài viết SO và nó * tuyệt vời * cho đến nay. Rất cám ơn Jeremy Skinner vì đã làm việc với nó .. – antinescience