One Message for rule chain?

ε祈祈猫儿з 提交于 2021-02-06 10:58:33

问题


I'm having an issue with FluentValidation where I want to display one message regardless of the validation error in a given chain. For example, I've defined a validation chain for one property below. I would expect that the chain would be evaluated and any failures would result in the message defined in the WithMessage() call below. However, it seems that it's short-circuiting and only displaying the FluentValidation default error message for the first error encountered. See code below:

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

What's happening is that the AgeMin property is null, so the first NotNull() check is failing and the validation message reads "'Proposal Detail. Age Min' must not be empty." Proposal Detail is the name of the encapsulating view model. I've tried setting the CascadeMode for the entire validator to CascadeMode.Continue, but it has no effect.

How can I accomplish one message for one property validation chain?


回答1:


Update 2

As it turns out,you can accomplish what you want with a simple extension method

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.Options.ErrorMessageSource=new StaticStringSource(errorMessage);

            return rule;
        }
    }
}

Update 3: (Apr 04/07/2019) In FluentValidation v8.2.2, The IRuleBuilderOptions interface do not have direct access to IRuleBuilderOptions.ErrorMessageSource property anymore, instead we should use: IRuleBuilderOptions.Options.ErrorMessageSource .




回答2:


The most straightforward solution would be to just set the message to a variable, and apply the same message after each rule:

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


来源:https://stackoverflow.com/questions/35513141/one-message-for-rule-chain

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!