流畅验证的链接规则

时间:2014-10-16 12:41:38

标签: c# fluent fluentvalidation

我已经在使用最新版本的Fluent Validation,即5.4.0.0;我需要实现的是:

考虑车辆VIN,这取决于Make Id,Model Id和制造年份。在Fluent中,我是否能够在成功执行这些规则时根据更多规则执行规则?

如果所有三条规则(品牌,型号和年份)都通过,我必须验证车辆vin。

我还阅读了整个文档,找不到任何实现它的参考。

class VehicleValidator : AbstractValidator<Vehicle>
{
    public VehicleValidator()
    {             
        RuleFor(v => v.MakeId)                
            .NotEmpty()
            .WithMessage("Make Id is required") 

        RuleFor(v => v.ModelId) 
            .NotEmpty()
            .WithMessage("Model Id is required")    

        RuleFor(v => v.Year)
            .NotEqual(default(ushort))                
            .WithMessage("Year is required")    

        RuleFor(v => v)
            .MustBeAValidVehicle()
            .WithName("Vehicle")
            .Unless(v => v.IdMarca == null || v.IdModelo == null && v.Ano == default(short));

        RuleFor(v => v.VehicleVin)
            .NotEmpty()
            .WithMessage("Vehicle Vin is required")         

        //Only run this validation if the validation of MakeId, ModelId, Year and MustBeAValidVechile don't fail
        RuleFor(v => v.VehicleVin)
            .MustBeAValidVehicleVin()
            .Unless(v => v.Chassi == null || v.IdMarca == null || v.IdModelo == null || v.Ano == default(ushort));
    }
}

2 个答案:

答案 0 :(得分:1)

您可以使用CascadeMode.StopOnFirstFailure组合VIN验证规则列表,以确保您只看到第一次失败。这将阻止任何额外的处理。

public class VinValidator : AbstractValidator<Vin>
{
    public VinValidator()
    {
        RuleFor(x => x.Vin)
            .Cascade(CascadeMode.StopOnFirstFailure)
            .Must(HaveValidMake).WithMessage("Invalid Make")
            .Must(HaveValidModel).WithMessage("Invalid Model")
            .Must(HaveValidYear).WithMessage("Invalid Year")
            .Must(BeValidVin).WithMessage("Invalid VIN");
    }

    private bool HaveValidMake(string vin)
    {
        return vin.Contains("make");
    }

    private bool HaveValidModel(string vin)
    {
        return vin.Contains("model");
    }

    private bool HaveValidYear(string vin)
    {
        return vin.Contains("year");
    }

    private bool BeValidVin(string vin)
    {
        return vin.Length == 17;
    }
}

以下示例演示了行为:

"invalid" => "Invalid Make"
"xxxmakexxx" => "Invalid Model"
"xxxmakemodelxxx" => "Invalid Year"
"xxxmakemodelyearxxx" => "Invalid VIN"
"xxxmakemodelyear" => valid

更新以反映示例代码:

如果AbstractValidator中没有进行其他验证,则可以将类级别属性CascadeMode设置为StopOnFirstFailure,以确保第一次失败时验证停止(请参阅here)。然后,您可以像在示例代码中那样将验证规则分开。

注意:在测试时,我注意到StopOnFirstFailure没有因非Must规则而受到尊重。您可能需要将规则转换为Must,如上所述。

答案 1 :(得分:1)

我找到了解决问题的方法。只需创建一个包含布尔属性的类,以确定是真还是假。

请参阅我在FLuent Validation讨论区的帖子 ValidationResultHolder - Rule Dependency