public class PersonDetailsViewModel
public bool? HasDetails { get; set; }
public BasicDetailsViewModel? BasicDetails { get; set; }
public class BasicDetailsViewModel
public string? FirstName { get; set; }
public string? Country { get; set; }
public class PersonDetailsViewModelValidator : AbstractValidator<PersonDetailsViewModel>
public PersonDetailsViewModelValidator()
RuleFor(model => model.BasicDetails)
.SetValidator(new BasicDetailsViewModelValidator())
.When(model => model.HasDetails == true);
RuleFor(model => model.BasicDetails)
.SetValidator(new DifferentValidator())
.When(model => model.HasDetails == false || model.HasDetails == null);
public class BasicDetailsViewModelValidator : AbstractValidator<BasicDetailsViewModel?>
public BasicDetailsViewModelValidator()
RuleFor(model => model.FirstName)
.NotEmpty().WithMessage("Name cannot be empty");
RuleFor(model => model.Country)
.NotEmpty().WithMessage("Country cannot be empty");
public class DifferentValidator : AbstractValidator<BasicDetailsViewModel?>
public DifferentValidator()
RuleFor(model => model.FirstName)
.Must(name => name == null || name.Length <= 10).WithMessage("First name must be 10 characters or less.");
RuleFor(model => model.Country)
.Must(country => country == null || country.All(char.IsUpper)).WithMessage("Country must be in uppercase.");
public static void Main()
var fail1 = new PersonDetailsViewModel { HasDetails = false, BasicDetails = new BasicDetailsViewModel { FirstName = "LongFirstNameThatFails", Country = "UK" } };
var fail2 = new PersonDetailsViewModel { HasDetails = false, BasicDetails = new BasicDetailsViewModel { FirstName = "John", Country = "lowercasecountry" } };
var fail3 = new PersonDetailsViewModel { HasDetails = true, BasicDetails = new BasicDetailsViewModel { FirstName = "", Country = "" } };
var fail4 = new PersonDetailsViewModel { HasDetails = false, BasicDetails = new BasicDetailsViewModel { FirstName = "LongFirstNameThatFails", Country = "lowercasecountry" } };
var pass1 = new PersonDetailsViewModel { HasDetails = false, BasicDetails = new BasicDetailsViewModel { FirstName = "John", Country = "UK" } };
var pass2 = new PersonDetailsViewModel { HasDetails = false, BasicDetails = null };
var validator = new PersonDetailsViewModelValidator();
PrintValidationResult(validator.Validate(fail1), "fail1:");
PrintValidationResult(validator.Validate(fail2), "fail2:");
PrintValidationResult(validator.Validate(fail3), "fail3:");
PrintValidationResult(validator.Validate(fail4), "fail4:");
PrintValidationResult(validator.Validate(pass1), "pass1:");
PrintValidationResult(validator.Validate(pass2), "pass2:");
public static void PrintValidationResult(FluentValidation.Results.ValidationResult result,string objectName)
Console.WriteLine(objectName);
Console.WriteLine("✅ Validation successful");
foreach (var error in result.Errors)
Console.WriteLine("❌ " + error.ErrorMessage);