2012-04-17 2 views
13

Ho un modello di vista MVC3 definito come:Come si esegue la convalida di ogni stringa in un elenco utilizzando Fluent Validation?

[Validator(typeof(AccountsValidator))] 
public class AccountViewModel 
{ 
    public List<string> Accounts { get; set; } 
} 

Con la convalida definite utilizzando FluentValidation (v3.3.1.0) come:

public class AccountsValidator : AbstractValidator<AccountViewModel> 
{ 
    public AccountsValidator() 
    { 
     RuleFor(x => x.Accounts).SetCollectionValidator(new AccountValidator()); //This won't work 
    } 
} 

e la convalida conto sarebbe forse essere definito:

public class AccountValidator : AbstractValidator<string> { 
    public OrderValidator() { 
     RuleFor(x => x).NotNull(); 
     //any other validation here 
    } 
} 

Vorrei che ogni account nell'elenco venisse eseguito come descritto nello documentation. Tuttavia, la chiamata a SetCollectionValidator non funziona in quanto non è un'opzione quando si utilizza uno List<string> sebbene l'opzione sarebbe presente se fosse definita come List<Account>. Mi sto perdendo qualcosa? Potrei cambiare il mio modello per usare List<Account> e quindi definire una classe Account ma non voglio davvero cambiare il mio modello per adattarlo alla convalida.

Per riferimento, questa è la vista che sto usando:

@model MvcApplication9.Models.AccountViewModel 

@using (Html.BeginForm()) 
{ 
    @*The first account number is a required field.*@ 
    <li>Account number* @Html.EditorFor(m => m.Accounts[0].Account) @Html.ValidationMessageFor(m => m.Accounts[0].Account)</li> 

    for (int i = 1; i < Model.Accounts.Count; i++) 
    { 
     <li>Account number @Html.EditorFor(m => m.Accounts[i].Account) @Html.ValidationMessageFor(m => m.Accounts[i].Account)</li> 
    } 

    <input type="submit" value="Add more..." name="add"/> 
    <input type="submit" value="Continue" name="next"/> 
} 

risposta

17

Il seguente dovrebbe funzionare:

public class AccountsValidator : AbstractValidator<AccountViewModel> 
{ 
    public AccountsValidator() 
    { 
     RuleFor(x => x.Accounts).SetCollectionValidator(
      new AccountValidator("Accounts") 
     ); 
    } 
} 

public class AccountValidator : AbstractValidator<string> 
{ 
    public AccountValidator(string collectionName) 
    { 
     RuleFor(x => x) 
      .NotEmpty() 
      .OverridePropertyName(collectionName); 
    } 
} 
+1

Grazie, SetCollectionValidator ha funzionato. Non sono del tutto sicuro del perché questa affermazione non fosse disponibile prima! Tuttavia, non funziona ancora abbastanza bene. La convalida viene utilizzata ma tutti gli errori vengono ora scritti nello stato del modello con una chiave di "Account [0]. Account". Uso ValidationMessageFor (m => m.Accounts [i]) nella vista per visualizzare ciascun numero di conto, pertanto ModelState dovrebbe avere una chiave di "Account [0]". Ho provato a cambiare OverridePropertyName (nomeRaccolta) usando un nome vuoto e rimuovendo completamente questa istruzione, ma ancora non riesco a farlo funzionare. – Dangerous

+0

Potrei farlo funzionare usando @ Html.ValidationMessage ("Account [i]. Account") ma ancora una volta sembra un lavoro da risolvere? Apprezzo i tuoi pensieri su questo? Grazie ancora. – Dangerous

+1

Ho deciso di utilizzare un modello di account anziché una stringa. Pertanto, gli errori sono ora riportati correttamente. Il nome della raccolta sopra non è quindi richiesto come parametro. – Dangerous

1

classi di convalida:

using FluentValidation; 
using System.Collections.Generic; 

namespace Test.Validator 
{ 

    public class EmailCollection 
    { 
     public IEnumerable<string> email { get; set; } 

    } 

    public class EmailValidator: AbstractValidator<string> 
    { 
     public EmailValidator() 
     { 
      RuleFor(x => x).Length(0, 5); 
     } 

    } 

    public class EmailListValidator: AbstractValidator<EmailCollection> 
    { 
     public EmailListValidator() 
     { 
      RuleFor(x => x.email).SetCollectionValidator(new EmailValidator()); 
     } 

    } 



} 

Nota: I ha utilizzato la versione più recente di MVC 5 (Nuget) di Fluentvalidation.

Problemi correlati