jasontaylordev/CleanArchitecture

Small bug, you can not reuse ValidationContext in ValidationBehaviour.cs

gevorgter opened this issue · 0 comments

File src/Application/Common/Behaviours/ValidationBehaviour.cs

Lines # 19-23

var context = new ValidationContext<TRequest>(request);

var validationResults = await Task.WhenAll(
    _validators.Select(v =>v.ValidateAsync(context, cancellationToken))
);

Unfortunately context is not thread safe and adds validation errors to collection (somewhere inside).

Steps to reproduce, have 2 validators for the same Request object, you will see that messages will duplicate. And occasionally (if you use real DB validation like BeUniqueTitle), you'll get error 'collection was modified..., when 2 threads will try to add error message simultaneously.
I rewrote it using simple foreach

List<FluentValidation.Results.ValidationFailure> failures = [];

foreach (var v in _validators)
{
    var context = new ValidationContext<TRequest>(request);
    var r = await v.ValidateAsync(context, cancellationToken);
    if (!r.IsValid)
        failures.AddRange(r.Errors);
}

Source for ValidationContext, Line 86 has "internal List Failures { get; }" which makes it not thread safe.
https://github.com/FluentValidation/FluentValidation/blob/main/src/FluentValidation/IValidationContext.cs