0

I'm already using the latest version of Fluent Validation which is 5.4.0.0; What I need to achieve is:

Think on a Vehicle VIN, which depends upon Make Id, Model Id and Year of manufacture. Does in Fluent I have the ability to execute a Rule based on more rules when these rules are successfully executed?

I must validate a vehicle vin if all three rules (Make, Model and Year) passes.

I've also read the whole documentation and couldn't find any reference to implement it.

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));
    }
}
gandarez
  • 2,609
  • 4
  • 34
  • 47
  • You can override Validate in your class that implements AbstractValidator if you want to customise how it validates the rules, but what are you trying to achieve? Why would do you want validation to be conditional, determined by the outcome of other validation, just validate everything every time. – Ben Robinson Oct 16 '14 at 12:55
  • @BenRobinson because do not make sense I show to user a message saying "vehicle vin is invalid". When I need to alert the user there's a invalid Make, Model or Year before validating it. – gandarez Oct 16 '14 at 12:58

2 Answers2

2

You can combine the list of VIN validation rules using CascadeMode.StopOnFirstFailure to ensure that you only see the first failure. This will prevent any additional processing.

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;
    }
}

The following examples demonstrate the behavior:

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

Update to reflect example code:

If there are no other validations being preformed in the AbstractValidator, then you can set the class level property CascadeMode to StopOnFirstFailure to ensure that the validation stops on the first failure (see here). You can then keep the validation rules separate as you have in your example code.

Note: When testing, I noticed that the StopOnFirstFailure was not being respected for non-Must rules. You may need to convert your rules to Musts as I have above.

bpruitt-goddard
  • 3,174
  • 2
  • 28
  • 34
1

I found out a workaround for my problem. Simply created a class which holds a boolean property to determine whether is true or false.

Please refer to my post on FLuent Validation discussion board ValidationResultHolder - Rule Dependency

gandarez
  • 2,609
  • 4
  • 34
  • 47
  • This may be what I need :) But the link appears to be broken Gandarez, can you pop it up somewhere or message it to me. – mattpm Feb 03 '17 at 00:33