ASP.NET Core: предотвращение автоматических ответов HTTP 400 для отдельных действий - PullRequest
0 голосов
/ 09 октября 2018

Мне нравится функция Автоматические ответы HTTP 400 , новая для ASP.NET Core 2.1, и она работает очень хорошо в большинстве случаев.

Однако, в одном действии мне нужно выполнитьнемного предварительной обработки перед проверкой полезной нагрузки.У меня есть собственный валидатор, которому для проверки требуется два значения в модели.Одно из этих значений находится в пути, поэтому я хотел бы установить это значение для модели из пути, а затем проверить.

Я не хочу отключать функциональность для всех действий с помощью:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<ApiBehaviorOptions>(options =>
    {
        options.SuppressModelStateInvalidFilter = true;
    });
}

Можно ли как-нибудь отключить его только для отдельного действия?

Редактировать:

Я пытался изменить InvalidModelStateResponseFactory, но это не удалосьрешить мою проблему, потому что мне все еще нужно войти в действие контроллера:

services.Configure<ApiBehaviorOptions>(options =>
{
    options.InvalidModelStateResponseFactory = actionContext =>
    {
        var ignore = actionContext.ActionDescriptor.FilterDescriptors.Any(fd => fd.Filter is SuppressModelStateInvalidFilterAttribute);
        if (ignore)
        {
            // Can only return IActionResult so doesn't enter the controller action.
        }

        return new BadRequestObjectResult(actionContext.ModelState);
    };
});

[AttributeUsage(AttributeTargets.Method)]
public class SuppressModelStateInvalidFilterAttribute : FormatFilterAttribute
{
}

Редактировать:

Вот ссылка на проблему, которую я поднял на asp.netБазовое репо на случай, если я с этим доберусь - https://github.com/aspnet/Mvc/issues/8575

Ответы [ 4 ]

0 голосов
/ 29 мая 2019

Обновление: вы можете просто использовать следующий код в ConfigureServices в Startup.cs:

services.Configure<ApiBehaviorOptions>(apiBehaviorOptions => {
    apiBehaviorOptions.SuppressModelStateInvalidFilter = true;
});

Исходя из ответа Саймона Вейна, мне пришлось изменить атрибут дляASP.Net Core 2.2 выглядит следующим образом:

/// <summary>
/// Suppresses the default ApiController behaviour of automatically creating error 400 responses
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class SuppressModelStateInvalidFilterAttribute : Attribute, IActionModelConvention {
    private static readonly Type ModelStateInvalidFilterFactory = typeof(ModelStateInvalidFilter).Assembly.GetType("Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilterFactory");

    public void Apply(ActionModel action) {
        for (var i = 0; i < action.Filters.Count; i++) {
            if (action.Filters[i] is ModelStateInvalidFilter || action.Filters[i].GetType() == ModelStateInvalidFilterFactory) {
                action.Filters.RemoveAt(i);
                break;
            }
        }
    }
}
0 голосов
/ 09 октября 2018

Вы можете поиграть со свойством ApiBehaviorOptions.InvalidModelStateResponseFactory для обработки конкретных случаев на основе actionContext подробностей:

services.Configure<ApiBehaviorOptions>(options =>
{
    options.InvalidModelStateResponseFactory = actionContext => 
    {
        // Do what you need here for specific cases with `actionContext` 
        // I believe you can cehck the action attributes 
        // if you'd like to make mark / handle specific cases by action attributes. 

        return new BadRequestObjectResult(context.ModelState);
    }
});
0 голосов
/ 10 октября 2018

У меня был ответ от Microsoft - https://github.com/aspnet/Mvc/issues/8575

Следующее сработало(обратите внимание, что ModelState.Clear (), TryValidateModel добавляет к существующему состоянию модели):

if (model == null)
{
    return BadRequest(ModelState);
}

model.Property = valueFromPath;

ModelState.Clear();
if (TryValidateModel(model) == false)
{
    return BadRequest(ModelState);
}
0 голосов
/ 09 октября 2018

Вероятно, это можно решить, внедрив собственный валидатор для вашего конкретного случая.Это довольно хорошо описано в документации.

https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-2.1#custom-validation

Либо это, либо, возможно, пользовательская привязка модели для создания вашей модели со всей предварительной обработкой, выполненной до ее проверки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...