2014-10-16 81 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