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

时间:2021-07-10 04:04:55

I have this controller

我有这个控制器

[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();
    }
}

Both the GET and POST request returns a statuscode of 500. This is the expected behavior.

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

But when I add app.UseExceptionHandler("/api/debug/error"); In the Startup.cs file, the POST request does no longer return a statuscode of 500, instead it returns 404. The GET request is still working as it should by returning a statuscode of 500.

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

DebugController

DebugController

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


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

Any idé why adding app.UseExceptionHandler("/api/debug/error"); would make the POST request behave this way?

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

A repo to reproduce this behavior can be found Here.

可以在此处找到重现此行为的repo。

1 个解决方案

#1


4  

When using ExceptionHandlerMiddleware with an ExceptionHandlingPath, as in your example, the main outcome is that the request path gets rewritten to instead use your new path (/api/debug/error in your case). You can see how this works in the source:

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

if (_options.ExceptionHandlingPath.HasValue)
{
    context.Request.Path = _options.ExceptionHandlingPath;
}

If you continue to browse through the source, you'll see that the StatusCode gets set to 500, but the original request is left mostly intact.

如果您继续浏览源代码,您将看到StatusCode设置为500,但原始请求大部分保持不变。

In practical terms, this means you are being sent to a POST action on your DebugController, but you have only provided a GET action.

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

A simple way to fix this would be to make your Index action support both GET and POST, like so:

解决此问题的一种简单方法是使您的索引操作同时支持GET和POST,如下所示:

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

If you want to do something different for POST errors, you can just create a new action, decorated with [HttpPost("error")].

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

#1


4  

When using ExceptionHandlerMiddleware with an ExceptionHandlingPath, as in your example, the main outcome is that the request path gets rewritten to instead use your new path (/api/debug/error in your case). You can see how this works in the source:

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

if (_options.ExceptionHandlingPath.HasValue)
{
    context.Request.Path = _options.ExceptionHandlingPath;
}

If you continue to browse through the source, you'll see that the StatusCode gets set to 500, but the original request is left mostly intact.

如果您继续浏览源代码,您将看到StatusCode设置为500,但原始请求大部分保持不变。

In practical terms, this means you are being sent to a POST action on your DebugController, but you have only provided a GET action.

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

A simple way to fix this would be to make your Index action support both GET and POST, like so:

解决此问题的一种简单方法是使您的索引操作同时支持GET和POST,如下所示:

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

If you want to do something different for POST errors, you can just create a new action, decorated with [HttpPost("error")].

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