2016-02-19 50 views
7

我遇到了FluentValidation问题,我想显示一条消息,而不管给定链中的验证错误。例如,我为下面的一个属性定义了一个验证链。我期望链会被评估,任何失败都会导致下面WithMessage()调用中定义的消息。但是,它似乎是短路并且仅显示遇到的第一个错误的FluentValidation默认错误消息。请参见下面的代码:规则链的一条消息?

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

发生了什么事是,AgeMin属性为空,所以第一个NotNull()检查失败,验证消息的内容“的议案‘详细年龄最小’不能为空。” Proposal Detail是封装视图模型的名称。 我已经尝试将整个验证器的CascadeMode设置为CascadeMode.Continue,但它没有效果。

如何为一个属性验证链完成一条消息?

+0

'使用上面的代码,将返回默认验证消息,而不是客户汤姆消息在最后'哪里是默认消息声明..?你是否可以发布所有相关的代码..还有你检查了[.NET文档/示例的流畅验证](https://fluentvalidation.codeplex.com/wikipage?title=CreatingAValidator) – MethodMan

+0

是的,我已经搜遍了文档, t找到了一个类似的例子。我想我必须使用一个规则来使用Must()来封装所有的规则来完成我想要做的事情。我会认为它是一个简单的用例。默认的FluentValidation消息返回''建议明细。 Age Min'不能为空',因为'NotNull()'是链中的第一个调用。我已经尝试为验证器设置'CascadeMode = CascadeMode.Continue',它没有任何效果。 – TimeBomb006

+0

请提供一个演示您的问题的[mcve]。它必须是我们可以运行的可编译代码。 – Enigmativity

回答

7

更新2

事实证明,你可以完成你想要的一个简单的扩展方法

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

您的更新2是正确的答案。我打算看看类似的解决方案,但你打败了我。 – devuxer

+0

@devuxer我只留下了以前的教育目的 –

+1

@GeorgeVovos这是一个优秀的,优雅的解决这个问题的方法。我已确认该解决方案按预期执行。谢谢! – TimeBomb006

3

到刚刚设置的消息变量最简单的解决办法是,并在每条规则后应用相同的消息:

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

我实际上使用这个解决方案,直到我看到乔治的编辑。两种方法都是可行的,但我喜欢乔治解决方案的清洁。 – TimeBomb006

+0

当您需要为不同的验证规则分配不同的消息时,可以使用此方法。 – user1176058