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.
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.
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?
A repo to reproduce this behavior can be found Here .
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 :
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.
In practical terms, this means you are being sent to a POST action on your DebugController
, but you have only provided a GET action.
A simple way to fix this would be to make your Index
action support both GET
and POST
, like so:
[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")]
.
Update: Some of this explanation now exists in the docs :
The exception handling middleware re-executes the request using the original HTTP method. If an error handler endpoint is restricted to a specific set of HTTP methods, it runs only for those HTTP methods. For example, an MVC controller action that uses the
[HttpGet]
attribute runs only for GET requests. To ensure that all requests reach the custom error handling page, don't restrict them to a specific set of HTTP methods.To handle exceptions differently based on the original HTTP method:
- For Razor Pages, create multiple handler methods. For example, use
OnGet
to handle GET exceptions and useOnPost
to handle POST exceptions.- For MVC, apply HTTP verb attributes to multiple actions. For example, use
[HttpGet]
to handle GET exceptions and use[HttpPost]
to handle POST exceptions.
I think I've been having a similar problem. I made an API controller callable from JavaScript. Everything works fine on development. I have noticed for a while that the API on the live site often returns a 404 error, even though the route is obviously there.
I think I have tracked down the issue which was 500 errors caused by subtle differences on the live site, most notably using a different version of the SQL database on live and dev. So basically my API's GET method was returning a 404 when it should have been returning 500. It sounds as if the solution is to ensure my API methods have both [HttpGet] and [HttpPost] attributes.
One other issue I have noticed is that API calls are sometimes cached if you use:
app.UseResponseCaching();
in Startup.cs. This very much depends on your hosting environment. I append a random number to my API route that resolves this.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.