FluentValidation自定义验证规则链问题

问题描述

我正在尝试使用自定义验证程序来验证智能枚举(Ardalis.S@R_404_4946@um)

这是枚举的类:

public abstract class FeelingSystemType : S@R_404_4946@um<FeelingSystemType>
{
    public static FeelingSystemType Positive = new PositiveType();
    public static FeelingSystemType Negative = new NegativeType();

    private FeelingSystemType(string name,int value) : base(name,value) { }

    private class PositiveType : FeelingSystemType
    {
        internal PositiveType() : base(nameof(Positive),1) { }
    }

    private class NegativeType : FeelingSystemType
    {
        internal NegativeType() : base(nameof(Negative),2) { }
    }
}

这是命令:

public class Command : IRequest<CommandResponsem>
{
    public Command() { }

    [JsonConverter(typeof(S@R_404_4946@umNameConverter<FeelingSystemType,int>))]
    public FeelingSystemType Feeling { get; set; }
}

这是命令验证器:

public class CommandValidator : AbstractValidator<Command>
{
    public CommandValidator()
    {
        RuleFor(r => r.Feeling).ValidateFeeling();
    }
}

这是自定义验证规则:

public static IRuleBuilder<T,FeelingSystemType> ValidateFeeling<T>(this IRuleBuilder<T,FeelingSystemType> rule)
{
    return rule
        .NotEmpty()
            .WithMessage("A Feeling must be entered")
        .Must(feeling => typeof(FeelingSystemType).IsAssignableFrom(feeling?.GetType()))
            .WithMessage("Please enter a valid Feeling");
}

当我发送请求时,验证器似乎忽略了NotEmpty在规则的Must部分之前,并且即使Feeling为null时仍继续验证Must,但同时返回了两条消息。我尝试在命令验证器中进行验证,除非获得NotEmpty和Must作为两个单独的规则,否则我将获得相同的结果。我非常有信心Fluent允许链接,所以我不确定这是怎么回事?

解决方法

默认FV行为将贯穿该属性的所有规则。如果要在遇到首次故障时停止,则需要执行诸如设置cascade mode之类的操作。

可以在几个地方完成操作,具体取决于您希望如何应用行为:

  • 使用静态选项(ValidatorOptions.Global.CascadeMode = CascadeMode.Stop;)在您应用的早期位置
  • 在使用CascadeMode = CascadeMode.Stop;的验证器中
  • 关于使用RuleFor(r => r.Feeling).Cascade(CascadeMode.Stop).ValidateFeeling();的规则

您的扩展程序捆绑了2条规则,您可以 在此处指定级联,但是您需要使用IRuleBuilderInitial界面。我怀疑这意味着您不能将该规则与属性验证程序中的其他规则链接在一起,除非它是第一条规则。无论如何可能都是最好的,因为它将混淆验证器的级联模式,该验证器具有某种气味。