В моем контроллере я использую шаблон-посредник для удаления свойства
public async Task<IActionResult> Delete(int propertyId)
{
await _mediator.Send(new DeletePropertyCommand(propertyId));
return NoContent();
}
Далее я проверяю DeletePropertyCommand
, используя свободную проверку, которая проверяет, существует ли она в db
RuleFor(property => property).MustAsync(Exist).MustAsync(BeOwnedByCurrentUser);
Если беглая проверка обнаруживает какую-либо ошибку, она обрабатывается в конвейере mediatr - в настоящее время я генерирую исключение ValidationException, которое обрабатывается в глобальном классе ErrorHandler:
public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
private readonly IEnumerable<IValidator<TRequest>> _validators;
public ValidationBehavior(IEnumerable<IValidator<TRequest>> validators)
{
_validators = validators;
}
public Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
var context = new ValidationContext(request);
var errors = _validators
.Select(v => v.Validate(context))
.SelectMany(result => result.Errors)
.Where(f => f != null)
.ToList();
return !errors.Any() ? next() : throw new ValidationException(errors);
}
}
Класс обработчика ошибок:
public class ErrorHandler
{
private readonly RequestDelegate _next;
public ErrorHandler(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception ex)
{
// if ex is of type ValidationException -> get errors, serialize them, return bad request
}
}
То, что я ищу, это какой-то способ избежать создания исключений, которые стоят дорого и просто возвращают неверный ответ на запрос с соответствующими ошибками.