FluentValidation 自定义验证规则链问题

Posted

技术标签:

【中文标题】FluentValidation 自定义验证规则链问题【英文标题】:FluentValidation Custom Validation Rule chain issue 【发布时间】:2021-01-14 22:12:07 【问题描述】:

我正在尝试使用自定义验证器来验证智能枚举 (Ardalis.SmartEnum)

这是枚举的类:

public abstract class FeelingSystemType : SmartEnum<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(SmartEnumNameConverter<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 为空,它仍然继续验证 Must,但同时返回两条消息。我尝试在命令验证器中进行验证,并且得到相同的结果,除非我将 NotEmpty 和 Must 作为两个单独的规则执行。我非常有信心 Fluent 允许链接,所以我不确定这里出了什么问题?

【问题讨论】:

【参考方案1】:

默认的 FV 行为是运行属性的所有规则。如果您想在遇到第一次失败时停止,您需要执行设置cascade mode 之类的操作。

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

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

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

【讨论】:

在使用依赖注入从汇编中加载验证器时如何设置全局选项? 它是静态的,因此您可以尽早设置它。例如,对于一个 asp.net mvc 核心 web 应用程序,您可以在启动时添加 fv do DI 容器。

以上是关于FluentValidation 自定义验证规则链问题的主要内容,如果未能解决你的问题,请参考以下文章

FluentValidation在C#中是怎么进行数据验证的

使用 FluentValidation 在一条规则中进行多重验证

验证规则构建神器 FluentValidation.md

FluentValidation 返回错误时如何返回自定义响应?

Blazor WASM - 流畅的验证

FluentValidation 和服务器+客户端远程验证器