2016-02-19 15 views
7

Mam problem z FluentValidation, w którym chcę wyświetlić jedną wiadomość niezależnie od błędu sprawdzania poprawności w danym łańcuchu. Na przykład zdefiniowałem łańcuch sprawdzania poprawności dla jednej usługi poniżej. Spodziewam się, że łańcuch zostanie poddany ewaluacji, a wszelkie awarie spowodują, że komunikat zdefiniowany w poniższym zgłoszeniu WithMessage(). Wydaje się jednak, że jest to zwarcie i wyświetlany jest tylko domyślny komunikat błędu FluentValidation dotyczący pierwszego napotkanego błędu. Zobacz poniższy kod:Jedna wiadomość dla łańcucha reguł?

RuleFor(s => s.ProposalDetail.AgeMin).NotNull() 
     .GreaterThanOrEqualTo(1) 
     .LessThanOrEqualTo(99) 
     .WithMessage("Minimum Age entry is required and must range from 1 to 99 years."); 

Co się dzieje jest to, że nieruchomość AgeMin jest zerowy, więc pierwsza NotNull() check się niepowodzeniem i wiadomość walidacji czyta „«Wniosek Detail Wiek Min.»Nie może być puste.” Szczegóły oferty to nazwa modelu widoku z otoczeniem. Próbowałem ustawić ustawienie CascadeMode dla całego walidatora na CascadeMode.Continue, ale nie ma ono żadnego efektu.

Jak mogę wykonać jedną wiadomość dla jednego łańcucha sprawdzania poprawności właściwości?

+0

'W powyższym kodzie zwracana jest domyślna wiadomość sprawdzania poprawności, zamiast cus tom wiadomość na końcu "gdzie jest zadeklarowana domyślna wiadomość ...? czy możesz opublikować cały odpowiedni kod. Czy sprawdziłeś także [fluentwalność dla .NET Documentation/Exxples // Usluga Acididation.codeplex.com/wikipage?title=CreatingAValidator) – MethodMan

+0

Tak, przetrząsnąłem dokumentację i pozwoliłem ' t znalazł podobny przykład. Wyobrażam sobie, że muszę użyć jednej reguły za pomocą 'Must()', aby hermetyzować wszystkie reguły, aby osiągnąć to, co próbuję zrobić. Myślałem, że to prosty przypadek. Domyślny komunikat FluentValidation zwraca "Szczegóły oferty. Age Min "nie może być pusty", ponieważ 'NotNull()' jest pierwszym wywołaniem w łańcuchu. Próbowałem ustawić 'CascadeMode = CascadeMode.Continue' dla walidatora, który nie miał żadnego efektu. – TimeBomb006

+0

Podaj [mcve], która pokazuje Twój problem. Musi to być kod kompilowany, który możemy uruchomić. – Enigmativity

Odpowiedz

7

Aktualizacja 2

Jak się okazuje, można osiągnąć to, co chcesz w prosty sposób wydłużania

using FluentValidation; 
using FluentValidation.Internal; 
using FluentValidation.Resources; 
using FluentValidation.Results; 
using System; 
using System.Linq; 

namespace ConsoleApplication9 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      Customer customer = new Customer() { }; 
      CustomerValidator validator = new CustomerValidator(); 
      ValidationResult results = validator.Validate(customer); 
      Console.WriteLine(results.Errors.First().ErrorMessage); 
      Console.ReadLine(); 
     } 
    } 
    public class CustomerValidator : AbstractValidator<Customer> 
    { 
     public CustomerValidator() 
     { 

      RuleFor(s => s.Id).NotNull() 
          .GreaterThanOrEqualTo(1) 
          .LessThanOrEqualTo(99) 
          .WithGlobalMessage("Minimum Age entry is required and must range from 1 to 99 years."); 
     } 

    } 

    public class Customer { public int? Id { get; set; } } 

    public static class MyExtentions 
    { 
     public static IRuleBuilderOptions<T, TProperty> WithGlobalMessage<T, TProperty>(this IRuleBuilderOptions<T, TProperty> rule, string errorMessage) 
     { 
      foreach (var item in (rule as RuleBuilder<T, TProperty>).Rule.Validators) 
       item.ErrorMessageSource=new StaticStringSource(errorMessage); 

      return rule; 
     } 
    } 
} 
+1

Twoja aktualizacja 2 jest właściwą odpowiedzią. Miałem zamiar przyjrzeć się podobnemu rozwiązaniu, ale mnie to pobiło. – devuxer

+0

@devuxer Opuściłem tylko poprzednie w celach edukacyjnych. –

+1

@GeorgeVovos To doskonałe, eleganckie rozwiązanie tego problemu. Potwierdziłem, że rozwiązanie działa zgodnie z oczekiwaniami. Dzięki! – TimeBomb006

3

Najprostszym rozwiązaniem byłoby po prostu ustawić wiadomość do zmiennej, i zastosuj tę samą wiadomość po każdej regule:

var message = "Minimum Age entry is required and must range from 1 to 99 years."; 
RuleFor(s => s.ProposalDetail.AgeMin) 
    .NotNull() 
     .WithMessage(message) 
    .GreaterThanOrEqualTo(1) 
     .WithMessage(message) 
    .LessThanOrEqualTo(99) 
     .WithMessage(message); 
+1

Tak naprawdę używałem tego rozwiązania, dopóki nie zobaczyłem edycji George'a. Oba podejścia są opłacalne, ale lubię czystość rozwiązania George'a. – TimeBomb006

+0

To podejście może być używane, gdy trzeba przydzielić różne komunikaty dla różnych reguł sprawdzania poprawności. – user1176058

Powiązane problemy