使用ExceptionHandler PipeLine时,ASP.NET Core返回404而不是500

use*_*253 8 c# asp.net asp.net-mvc asp.net-core

我有这个控制器

[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values
    [HttpGet]
    public IEnumerable<string> Get()
    {
        Console.WriteLine("GET Index");
        throw new Exception();
    }

    // POST api/values
    [HttpPost]
    public void Post()
    {
        Console.WriteLine("POST Index");
        throw new Exception();
    }
}
Run Code Online (Sandbox Code Playgroud)

GET和POST请求都返回500的状态代码.这是预期的行为.

但是当我app.UseExceptionHandler("/api/debug/error"); 在Startup.cs文件中添加时,POST请求不再返回状态代码500,而是返回404.GET请求仍然可以正常工作,返回状态代码500.

DebugController

[Route("api/[controller]")]
public class DebugController : Controller
{


    [HttpGet("error")]
    public IActionResult Index()
    {
        return StatusCode(500,"Hello, World! From debug controller");
    }
}
Run Code Online (Sandbox Code Playgroud)

任何为什么添加idé app.UseExceptionHandler("/api/debug/error");会使POST请求以这种方式运行?

可以在此处找到重现此行为的回购.

Kir*_*kin 7

ExceptionHandlerMiddleware与ExceptionHandlingPath一起使用时,如您的示例所示,主要结果是请求路径被重写为使用您的新路径(/api/debug/error在您的情况下).您可以在源代码中看到它的工作原理:

if (_options.ExceptionHandlingPath.HasValue)
{
    context.Request.Path = _options.ExceptionHandlingPath;
}
Run Code Online (Sandbox Code Playgroud)

如果您继续浏览源代码,您将看到StatusCodegets设置为500,但原始请求基本保持不变.

实际上,这意味着您将被发送到您的POST操作DebugController,但您只提供了GET操作.

一个简单的办法解决这一问题将是使你的Index行动同时支持GETPOST,就像这样:

[HttpGet("error")]
[HttpPost("error")]
public IActionResult Index()
{
    return StatusCode(500,"Hello, World! From debug controller");
}
Run Code Online (Sandbox Code Playgroud)

如果你想为POST错误做一些不同的事情,你可以创建一个新的动作,用[HttpPost("error")].