2012-04-17 11 views
13

ich ein MVC3 View-Modell haben wie folgt definiert:Wie validiert man mit Hilfe von Fluent Validation gegen jeden String in einer Liste?

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

Mit der Validierung mit FluentValidation definiert (v3.3.1.0) als:

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

und das Konto Validierung möglicherweise definiert werden würde:

Ich möchte, dass jedes Konto in der Liste wie im documentation beschrieben validiert wird. Der Aufruf von SetCollectionValidator funktioniert jedoch nicht, da dies keine Option ist, wenn Sie eine List<string> verwenden, obwohl die Option vorhanden wäre, wenn sie als List<Account> definiert wäre. Fehle ich etwas? Ich könnte mein Modell ändern, um List<Account> zu verwenden und dann eine Konto-Klasse zu definieren, aber ich möchte nicht wirklich mein Modell ändern, um der Überprüfung zu entsprechen.

Als Referenz ist dies die Ansicht, die ich benutze:

@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"/> 
} 

Antwort

17

Folgende Arbeiten sollten:

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

Vielen Dank, SetCollectionValidator hat funktioniert. Ich bin mir nicht ganz sicher, warum diese Aussage vorher nicht verfügbar war! Es funktioniert jedoch immer noch nicht ganz richtig. Die Validierung wird verwendet, aber alle Fehler werden jetzt mit dem Schlüssel "Accounts [0] .Accounts" in den Modellstatus geschrieben. Ich verwende ValidationMessageFor (m => m.Accounts [i]) in der Ansicht, um jede Kontonummer anzuzeigen, daher sollte ModelState einen Schlüssel von "Accounts [0]" haben. Ich habe versucht, OverridePropertyName (collectionName) zu ändern, indem ich einen leeren Namen verwende und diese Anweisung vollständig lösche, aber immer noch nicht funktioniert. – Dangerous

+0

Ich könnte es mit @ Html.ValidationMessage ("Accounts [i] .Accounts") arbeiten, aber das scheint wieder wie eine Arbeit zu sein? Ich schätze deine Gedanken dazu? Danke noch einmal. – Dangerous

+1

Ich habe mich entschieden, ein Account-Modell anstelle einer Zeichenfolge zu verwenden. Daher werden die Fehler jetzt korrekt gemeldet. Der obige Sammlungsname wird daher nicht als Parameter benötigt. – Dangerous

1

Klassen Validierung:

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

    } 



} 

Hinweis: I verwendete letzte MVC 5 (Nuget) Version von fluentvalidation.

Verwandte Themen