Home > front end >  Fluent Validate with same method multiple properties
Fluent Validate with same method multiple properties

Time:08-29

public class ModelToValidate
{
   public int CustomerId { get; set; }
   public int CarId { get; set; }
   public int CustomerPartnerId { get; set; }
   ...
}

public class ModelToValidateValidator: AbstractValidator<ModelToValidate>
{
   ...
   RuleFor(v => v.CustomerId).MustAsync(
        async (model) =>
        {
            return await CustomerFound(model.CustomerId, model.CarId);
        }
     ).WithMessage("{PropertyName} message.");

 RuleFor(v => v.CustomerPartnerId).MustAsync(
            async (model) =>
            {
                return await CustomerFound(model.CustomerPartnerId, model.CarId);
            }
         ).WithMessage("{PropertyName} message.");

  private async Task<bool> CustomerFound(int custId, int carId)
  {
    return await _repository.Customers(custId, carId);
  }
}

I want to validate model with same method (CustomerFound) for multiple properties in my model (first I want to check combination of CustomerId CarID and secondly CustomerPartnerId CarId). This code above doesn't compile

CodePudding user response:

You can do this using an extension method. Something like that:

public static class FluentValidationExtensions
{
    public static IRuleBuilderOptions<T, TValue> CustomValidationMethod<T, TValue>(this IRuleBuilder<T, TValue> ruleBuilder)
    {
        // some shared validation logic
    }
}

In your case, I think it should look like this:

public static class FluentValidationExtensions
{
    public static IRuleBuilderOptions<ModelToValidate, int> MustExistsAsync(this IRuleBuilder<ModelToValidate, int> ruleBuilder, IRepo repository)
    {
        return ruleBuilder.MustAsync(
            async (model) =>
            {
                return await CustomerFound(model.CustomerPartnerId, model.CarId);
            }
         ).WithMessage("{PropertyName} message.")
    }

    private static async Task<bool> CustomerFound(IRepo repository, int custId, int carId)
    {
        return await repository.Customers(custId, carId);
    }
}

And after that you can call it like other validation methods:

public class ModelToValidateValidator: AbstractValidator<ModelToValidate>
{

    ...
    RuleFor(v => v.CustomerId).MustExistsAsync(_repository);
    RuleFor(v => v.CustomerPartnerId).MustExistsAsync(_repository);
    ...
}
  • Related