Search code examples
c#asp.net-corefluentvalidation

Injecting conditions into FluentValidation rule


Is it possible to inject a condition (like a regex string, or integer) into a FluentValidation validator? That is, say I have multiple clients where each has different password requirements; can I inject that into the validator?

Something like:

public RegistrationValidator(int minLength, string regex)
{
    RuleFor(registration => registration.Login).MinimumLength(minLength);
    RuleFor(registration => registration.Password).Matches(regex);
}

If so, how exactly is it done? The closest I can figure is with root context data, but I feel like this should be simpler than that.


Solution

  • Yes, it's possible. you can inject any services you want from the constructor method in the validation class and create your custom validator. to define a rule like that you have 3 options.

    1 - When / WhenAsync

    2 - Must / MustAsync

    3 - Custom / CustomAsync

    For example, I want to inject my DbContext in the validator class, load the user and create a suitable validation for the current user.

    User Class :

    public class User
    {
        public int Id { get; set; }
        public string PhoneNumber { get; set; }
        public string PhoneNumberRegax { get; set; }
    }
    

    DTO class :

    public class UserDto
    {
        public int Id { get; set; }
        public string PhoneNumber { get; set; }
    }
    

    Validator Class

    public class UserDtoValidator : AbstractValidator<UserDto>
    {
        private readonly UserDbContext _context;
        public UserDtoValidator(UserDbContext context)
        {
            _context = context;
            RuleFor(x => x).Must(CheckPhoneNumberRegax);
        }
    
        private bool CheckPhoneNumberRegax(UserDto inputUser)
        {
            var user = _context.Users.Single(o => o.Id = inputUser.Id);
        
            var r = new Regex(user.PhoneNumberRegax, RegexOptions.IgnoreCase);
            return r.IsMatch(inputUser.PhoneNumber);
        }
    }
    

    Note: if use FluentValiation as ASP.NET Core Default validator must not use Async methods in the validator because ASP.NET Core validation pipeline is synchronous.