2014-10-16 83 views
0

我已经使用最新版本的Fluent Validation 5.4.0.0;我需要达到的是:流畅验证的链接规则

考虑汽车VIN,这取决于品牌ID,型号ID和制造年份。在流利中我是否有能力在这些规则成功执行时根据更多规则执行规则?

如果所有三条规则(品牌,型号和年份)都通过,我必须验证车辆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)); 
    } 
} 
+0

你可以在你的类,如果你想定制它的验证规则实现AbstractValidator 覆盖验证,但什么是你想达到什么目的?为什么你会希望验证是有条件的,由其他验证的结果决定,只是每次验证一切。 – 2014-10-16 12:55:07

+0

@BenRobinson因为没有意义,我向用户显示一个消息,说“车辆无效”。当我需要提醒用户时,在验证它之前有一个无效的品牌,型号或年份。 – Gandarez 2014-10-16 12:58:53

回答

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被预制没有其他验证,那么你可以设置级别级别属性CascadeModeStopOnFirstFailure,以确保验证在第一次失败时停止(请参阅here)。然后,您可以像在示例代码中那样保持验证规则分离。

注意:在测试时,我注意到StopOnFirstFailure没有遵守非必须规则。您可能需要将您的规则转换为Must,如上所述。

+0

请在我最初的主题中考虑我的更新。 – Gandarez 2014-10-17 14:00:44

1

我找到了解决我的问题的解决方法。简单地创建一个拥有布尔属性的类来确定是否为真。

请参考我的岗位上一口流利的验证讨论区 ValidationResultHolder - Rule Dependency

+0

这可能是我需要:)但链接似乎被打破甘地雷斯,你可以弹出它的地方或消息给我。 – mattpm 2017-02-03 00:33:44