【问题标题】:ASP.NET Core returns 404 instead of 500 when using ExceptionHandler PipeLineASP.NET Core 在使用 ExceptionHandler PipeLine 时返回 404 而不是 500
【发布时间】:2018-02-07 15:55:51
【问题描述】:

我有这个控制器

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

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

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

【问题讨论】:

  • 您有一个 Get 错误,但没有 Post 错误操作。

标签: c# asp.net asp.net-mvc asp.net-core


【解决方案1】:

当使用带有 ExceptionHandlingPath 的 ExceptionHandlerMiddleware 时,如您的示例所示,主要结果是请求路径被重写为使用您的新路径(在您的情况下为 /api/debug/error)。您可以在source 中看到这是如何工作的:

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

如果您继续浏览源代码,您会看到 StatusCode gets set to 500,但原始请求大部分保持不变。

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

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

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

如果您想为 POST 错误做一些不同的操作,您可以创建一个新操作,用[HttpPost("error")] 装饰。


更新:其中一些解释现在存在于docs

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

基于原始 HTTP 方法以不同方式处理异常:

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

【讨论】:

    【解决方案2】:

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

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

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

    app.UseResponseCaching();
    

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

    【讨论】:

      猜你喜欢
      • 2020-07-06
      • 2018-12-27
      • 1970-01-01
      • 2010-11-04
      • 2020-02-24
      • 2017-01-17
      • 2021-02-01
      • 2023-03-12
      • 1970-01-01
      相关资源
      最近更新 更多