How to use MustAsync in Pipeline
P9avel opened this issue · 2 comments
Hello, thank for you example. I am want to use Validator like
public class CustomerValidator : AbstractValidator
{
SomeExternalWebApiClient _client;
public CustomerValidator(SomeExternalWebApiClient client)
{
_client = client;
RuleFor(x => x.Id).MustAsync(async (id, cancellation) =>
{
bool exists = await _client.IdExists(id);
return !exists;
}).WithMessage("ID Must be unique");
}
}
When i am used this code, i am recive exception in line
public sealed class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : class, ICommand
{
private readonly IEnumerable<IValidator> _validators;
public ValidationBehavior(IEnumerable<IValidator> validators) => _validators = validators;
public async Task Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate next)
{
if (!_validators.Any())
{
return await next();
}
var context = new ValidationContext(request);
var errorsDictionary = _validators
.Select(x => x.Validate(context)) <-- Exceptions here, need to call ValidateAsync
.SelectMany(x => x.Errors)
.Where(x => x != null)
.GroupBy(
x => x.PropertyName,
x => x.ErrorMessage,
(propertyName, errorMessages) => new
{
Key = propertyName,
Values = errorMessages.Distinct().ToArray()
})
.ToDictionary(x => x.Key, x => x.Values);
Can you to modify code for old cases (sync validators) and for new case (MustAsync calls)?
Hi, maybe you have to do something like this :
var context = new ValidationContext<TRequest>(request);
var tasks = _validators.Select(x => x.ValidateAsync(context, cancellationToken));
var result = await Task.WhenAll(tasks);
var add = result.SelectMany(x => x.Errors)
.Where(x => x != null)
.GroupBy(
x => x.PropertyName,
x => x.ErrorMessage,
(propertyName, errorMessages) => new
{
Key = propertyName,
Values = errorMessages.Distinct().ToArray()
})
.ToDictionary(x => x.Key, x => x.Values);
then you have to combine Validate Dictionary + ValidateAsync. But I don't like this approach, I prefer to check it in Handler. The validator shouldn't be heavy.
many thx for your code