2012-12-26 8 views
5

ich derzeit ein Ansichtsmodell Setup als solche haben:Validieren Nested Modelle

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

... in diesem Fall „RequiredIfOtherPropertyIsTrue“ ein Validator ist so ziemlich das tut, was er sagt: überprüft, ob eine andere Eigenschaft ist true (in diesem Fall unsere Bedingung, die anzeigt, ob eine Anzahlung ist nicht erforderlich) und BankInfo ist ein weiteres Modell, das etwa wie folgt aussieht:

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

nun in unserem Ansichtsmodell haben wir eine Checkbox, gebunden an unsere DepositRequired Boolean und ein Editor für eine benutzerdefinierte Vorlage für BankInfo. Bei der Einreichung haben wir Probleme herauszufinden, wie deaktivieren Validierung auf BankInfo IF es ist nicht erforderlich für das Modell (z. B. auch wenn wir nicht die Eigenschaft auf dem ViewModel, es ist immer noch Val auf BankInfo und damit fehlgeschlagen kläglich auf irgendeiner Form Post). Gibt es eine Standardmethode für den Umgang mit der Validierung geschachtelter Modelle in der ViewModel-Bindung?

+0

Als Hinweis, auch wenn wir weg von BankInfo unseren benutzerdefinierten Validator rippen und lassen Sie es als undecorated Eigenschaft auf dem Ansichtsmodell, die BankInfo Validierung tritt noch in selbst wenn die Eigenschaft isn‘ an die Formularvorlage gebunden zu sein. – antinescience

+0

Der Grund für die Validierung von BankInfo ist, dass der Standardmodellbinder die untergeordneten Elemente des Modells vollständig bindet und validiert, bevor die Bindung abgeschlossen und das Containermodell selbst validiert werden kann. Ich bin mir nicht sicher, ob es einen Workaround dafür gibt, einen benutzerdefinierten Modellordner zu erstellen. – rossisdead

Antwort

5

Leider mit der Validierung gebaut, dann würden Sie

ModelState.Remove("BankInfo"); 

bedingt keine Validierung Ausfälle ignorieren für das Objekt verwenden.

Wenn FluentValidation mit einer Option ist, können Sie so etwas wie dies in Ihrem OurViewModelValidator tun:

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

und dann die BankInfoValidator Griff Validierung des Objekts lassen.

Etwas wie:

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 für [FluentValidation] (http://fluentvalidation.codeplex.com/) - fand es von einer Reihe anderer flüchtiger Blicke auf SO-Posts und es ist bis jetzt * super *. Vielen Dank an Jeremy Skinner für die Arbeit daran. – antinescience