[英]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 请求以这种方式运行吗?
可以在此处找到重现此行为的存储库。
当将ExceptionHandlerMiddleware
与ExceptionHandlerMiddleware
一起使用时,如在您的示例中一样,主要结果是请求路径被重写为使用您的新路径(在您的情况下为/api/debug/error
)。 您可以在源代码中看到这是如何工作的:
if (_options.ExceptionHandlingPath.HasValue)
{
context.Request.Path = _options.ExceptionHandlingPath;
}
如果您继续浏览源代码,您会看到StatusCode
设置为500
,但原始请求基本保持不变。
实际上,这意味着您将被发送到DebugController
上的 POST 操作,但您只提供了 GET 操作。
解决此问题的一种简单方法是使您的Index
操作同时支持GET
和POST
,如下所示:
[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.