繁体   English   中英

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

[英]ASP.NET Core returns 404 instead of 500 when using ExceptionHandler PipeLine

我有这个控制器

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

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

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

调试控制器

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


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

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

可以在此处找到重现此行为的存储库。

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

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

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

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

解决此问题的一种简单方法是使您的Index操作同时支持GETPOST ,如下所示:

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

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


更新:部分解释现在存在于文档中

异常处理中间件使用原始HTTP 方法重新执行请求。 如果错误处理程序端点仅限于一组特定的 HTTP 方法,则它仅针对这些 HTTP 方法运行。 例如,使用[HttpGet]属性的 MVC 控制器操作仅针对 GET 请求运行。 为确保所有请求都到达自定义错误处理页面,不要将它们限制为一组特定的 HTTP 方法。

根据原始 HTTP 方法以不同方式处理异常:

  • 对于 Razor Pages,创建多个处理程序方法。 例如,使用OnGet处理 GET 异常,使用OnPost处理 POST 异常。
  • 对于 MVC,将 HTTP 动词属性应用于多个操作。 例如,使用[HttpGet]处理GET异常,使用[HttpPost]处理POST异常。

我想我遇到了类似的问题。 我制作了一个可从 JavaScript 调用的 API 控制器。 在开发中一切正常。 一段时间以来,我注意到实时站点上的 API 经常返回 404 错误,即使该路由明显存在。

我想我已经找到了由实时站点上的细微差异引起的 500 个错误的问题,最显着的是在 live 和 dev 上使用不同版本的 SQL 数据库。 所以基本上我的 API 的 GET 方法在它应该返回 500 时返回了 404。听起来好像解决方案是确保我的 API 方法同时具有 [HttpGet] 和 [HttpPost] 属性。

我注意到的另一个问题是,如果您使用以下命令,API 调用有时会被缓存:

app.UseResponseCaching();

在 Startup.cs 中。 这在很大程度上取决于您的托管环境。 我在解决此问题的 API 路由中附加了一个随机数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM