Как подружить ValidationBehavior и LoggingBehavior в MediatR?
Прежде чем выполнить код в Handler, у меня есть два конвейера поведений:
LoggingBehavior
public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : class
where TResponse : class
{
public async Task<TResponse> Handle(TRequest request,
RequestHandlerDelegate<TResponse> next,
CancellationToken cancellationToken)
{
Serilog.Log.Information("Начало");
TResponse result = await next();
Serilog.Log.Information("Конец");
return result;
}
}
ValidationBehavior
public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
where TResponse : class
{
private readonly IEnumerable<IValidator<TRequest>> _validators;
public ValidationBehavior(IEnumerable<IValidator<TRequest>> validators)
{
_validators = validators;
}
public async Task<TResponse> Handle(
TRequest request,
RequestHandlerDelegate<TResponse> next,
CancellationToken cancellationToken)
{
if(!_validators.Any())
{
return await next();
}
var errors = _validators
.Select(validator => validator.Validate(request).ToString(";"))
.Where(errors => errors != "")
.Distinct()
.ToList();
if(errors.Any())
{
return new ObjectResult(errors)
{
StatusCode = StatusCodes.Status400BadRequest,
} as TResponse;
}
else
{
return await next();
}
}
}
Вот порядок их регистрации
builder.Services.AddScoped(
typeof(IPipelineBehavior<,>),
typeof(ValidationBehavior<,>));
builder.Services.AddScoped(
typeof(IPipelineBehavior<,>),
typeof(LoggingBehavior<,>));
При пройденной валидации идёт логирование, но при неудачно я возвращаю ошибку и дальше никуда не перехожу. Есть ли способ подружить эти конвейера, чтобы при неудачно валидации всё-равно было логирование но при этом код в Handler не выполнялся?
Я думал над созданием класс Result в котором будет свойство пройдена ли валидация, но тогда это свойство нужно будет проверять в Handler и это будет выглядеть как костыль.
Ответы (1 шт):
У вас в ValidationBehavior
возвращается ObjectResult
если валидация не прошла успешно. Попробуйте возвращать null
. Также сделайте проверку логгирования для ValidationBehavior
. То есть, если он вернет null
, то логгирование не выполняется.
Но! Использование дополнительного класса для передачи результата валидации не является костылем, поэтому можете реализовать и такой вариант.