我有这个控制器
[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.通过返回状态代码500,GET请求仍然可以正常工作。
DebugController
[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请求以这种方式运行?
可以找到重现此行为的仓库Here。
答案 0 :(得分:6)
将ExceptionHandlerMiddleware
与ExceptionHandlingPath一起使用时,如示例所示,主要结果是请求路径被重写为使用新路径(在您的情况下为/api/debug/error
)。您可以在source:
if (_options.ExceptionHandlingPath.HasValue)
{
context.Request.Path = _options.ExceptionHandlingPath;
}
如果您继续浏览来源,则会看到StatusCode
gets set to 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")]
修饰的新动作。
答案 1 :(得分:0)
我想我遇到了类似的问题。我制作了一个可从 JavaScript 调用的 API 控制器。在开发中一切正常。一段时间以来,我注意到实时站点上的 API 经常返回 404 错误,即使路由明显存在。
我想我已经找到了由实时站点上的细微差异引起的 500 个错误的问题,最明显的是在实时站点和开发站点上使用了不同版本的 SQL 数据库。所以基本上我的 API 的 GET 方法在应该返回 500 时返回了 404。听起来好像解决方案是确保我的 API 方法同时具有 [HttpGet] 和 [HttpPost] 属性。
我注意到的另一个问题是 API 调用有时会被缓存,如果您使用:
app.UseResponseCaching();
在 Startup.cs 中。这在很大程度上取决于您的托管环境。我在解决此问题的 API 路由中附加了一个随机数。