Хотите получить 405 (метод не разрешен) вместо 404 - PullRequest
4 голосов
/ 19 апреля 2019

Я пытаюсь получить 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);
}

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

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

1 Ответ

5 голосов
/ 19 апреля 2019

Поскольку 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 ActionPost

PUT-запрос

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

405 Метод не разрешен

...