FluentValidation использовать пользовательский IActionFilter - PullRequest
0 голосов
/ 26 января 2020

У меня есть пользовательский IActionFilter, который я регистрирую в своем приложении следующим образом:

services.AddControllers(options => options.Filters.Add(new HttpResponseExceptionFilter()));

Класс выглядит следующим образом:

public class HttpResponseExceptionFilter : IActionFilter, IOrderedFilter
{
    public int Order { get; set; } = int.MaxValue - 10;

    public void OnActionExecuting(ActionExecutingContext context)
    {
    }

    public void OnActionExecuted(ActionExecutedContext context)
    {
        if (context.Exception == null) return;

        var attempt = Attempt<string>.Fail(context.Exception);

        if (context.Exception is AttemptException exception)
        {
            context.Result = new ObjectResult(attempt)
            {
                StatusCode = exception.StatusCode,
            };
        }
        else
        {
            context.Result = new ObjectResult(attempt)
            {
                StatusCode = (int)HttpStatusCode.InternalServerError,
            };
        }

        context.ExceptionHandled = true;
    }
}

Я ожидаю, что при проверке его будет вызывать метод OnActionExecuting. Поэтому я добавил этот код:

public void OnActionExecuting(ActionExecutingContext context)
{
    if (!context.ModelState.IsValid)
    {
        context.Result = new BadRequestObjectResult(context.ModelState);
    }
}

И я поставил точку останова в начале метода, но когда я запускаю свое приложение и пытаюсь опубликовать недопустимую модель, я получаю этот ответ:

{
    "errors": {
        "Url": [
            "'Url' is invalid. It should start with 'https://www.youtube.com/embed'",
            "'Url' is invalid. It should have the correct parameter '?start='"
        ]
    },
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "|87e96062-42181357ba1ef8c5."
}

Как заставить FluentValidation использовать мой фильтр?

Ответы [ 2 ]

0 голосов
/ 27 января 2020

Лучшее решение, которое я нашел, было:

.ConfigureApiBehaviorOptions(options =>
{
    options.InvalidModelStateResponseFactory = context =>
    {
        var messages = context.ModelState.Values
            .Where(x => x.ValidationState == ModelValidationState.Invalid)
            .SelectMany(x => x.Errors)
            .Select(x => x.ErrorMessage)
            .ToList();

        return new BadRequestObjectResult(
            Attempt<string>.Fail(
                new AttemptException(string.Join($"{Environment.NewLine}", messages))));
    };
})
0 голосов
/ 27 января 2020

Когда применяется атрибут [ApiController], ASP. NET Ядро автоматически обрабатывает ошибки проверки модели, возвращая неверный запрос 400 с ModelState в качестве тела ответа:

Automati c HTTP 400 ответов

Чтобы отключить автоматическое поведение c 400, установите для свойства SuppressModelStateInvalidFilter значение true:

services.AddControllers()
    .ConfigureApiBehaviorOptions(options => 
    {   
        options.SuppressModelStateInvalidFilter = true;     
    });
...