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