Хотите получить 405 (метод запрещен) вместо 404

Я пытаюсь получить ошибку 405, если указан действительный маршрут, но метод HTTP не найден. В настоящее время приложение возвращает ошибку 404, поскольку для функции требуется соответствие маршрута и метода (ожидаемое поведение в MVC).

[HttpGet("api/action")]
public IActionResult ActionGet()
{
    // code
}

[HttpPost("api/action")]
public IActionResult ActionPost()
{
    //code
}

В этом примере, если я выполняю запрос DELETE или PUT, он не будет направлять ни одну из этих функций и просто вернет 404.

Мое текущее решение - создать функцию в каждом контроллере, в котором все маршруты жестко запрограммированы для перехвата запроса независимо от того, какой метод HTTP используется. Тогда это просто выдаст ошибку 405.

[Route("api/action", Order = 2)]
public IActionResult Handle405()
{
    return StatusCode(405);
}

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

Есть ли более чистое решение для обработки маршрутов так, как я хочу? Например, с использованием атрибутов или фильтров?


person Tom Dee    schedule 19.04.2019    source источник
comment
Попробуйте атрибут ProducesResponseType   -  person valerian Havaux    schedule 19.04.2019


Ответы (1)


Начиная с ASP.NET Core 2.2, MVC services по умолчанию поддерживает желаемое поведение. Убедитесь, что для версии совместимости служб MVC установлено значение Version_2_2 в ConfigureServices методе.

Startup.cs

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Пример

В демонстрационных целях я создал контроллер API, похожий на ваш.

ActionsController.cs

[Route("api/[controller]")]
[ApiController]
public class ActionsController : ControllerBase
{
    [HttpGet("action")]
    public IActionResult ActionGet()
    {
        return Ok("ActionGet");
    }

    [HttpPost("action")]
    public IActionResult ActionPost()
    {
        return Ok("ActionPost");
    }
}

Запрос GET

GET /api/actions/action HTTP/1.1
Host: localhost:44338

200 ActionGet

Запрос POST

POST /api/actions/action HTTP/1.1
Host: localhost:44338

200 Экшн

Запрос PUT

PUT /api/actions/action HTTP/1.1
Host: localhost:44338

405 Метод запрещен

person prd    schedule 19.04.2019