When I am reading about webapi for responding to requests and handling errors everything is based around:
IHttpActionResult
HttpResponseException
But when you create a .net core webapi project these are not available. I can find IActionResult, which seems to be the equivalent?
But I'm going round in circles trying to find out a really very simple thing, which is how to handle errors in a .net core webapi because HttpResponseException is not available. I get the impression everything with 'http' in it, is just for a full MVC application.
All I want to do is return an error, surely it must be simple...
IHttpActionResult contains a single method, ExecuteAsync, which asynchronously creates an HttpResponseMessage instance. If a controller action returns an IHttpActionResult, Web API calls the ExecuteAsync method to create an HttpResponseMessage. Then it converts the HttpResponseMessage into an HTTP response message.
An action method in Web API 2 can return an implementation of IHttpActionResult class which is more or less similar to ActionResult class in ASP.NET MVC.
IActionResult
is the equivalent of IHttpActionResult
, as you've suggested. This is part of the consolidation of what was known as MVC and Web API in ASP.NET Core MVC.
As for HttpResponseException
, this has been completely removed in ASP.NET Core. There's an interesting issue around this on GitHub, where David Fowler gives an explanation as to why this is the case:
Just the classic, "we don't want people using exceptions for control flow" paradigm. People did things like use it from within their business logic which is all sorts of wrong. I can't speak to the performance issues because I haven't measured but throwing an exception that is meant to be caught to get some data is worse than just returning that result.
The suggested alternative to this is to use the various IActionResult
implementations for creating JSON responses, returning errors, etc. Again, from the issue:
My suggestion would be to have the action method return IActionResult (or the async variation).
The reason that both IActionResult and object are supported is that they each suit different purposes and different styles. For some of the simplest cases, it's nice to use object, but it isn't powerful at all. For full control, there's IActionResult, which follows the well-known "command pattern."
The IActionResult pattern allows the controller to explicitly state what should happen as a result of the action: some kind of error code, a redirect, a serialized data object, a rendered view, etc.
If you're looking to handle errors outside of controllers, you might benefit from reading the docs on this topic, which goes into the details of using either middleware or filters for error-handling. In the comments, there's a link to a tutorial that explains some aspects of error-handling in more detail.
For completeness, here's the code from the tutorial for the middleware approach:
app.UseExceptionHandler(
options => {
options.Run(
async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.ContentType = "text/html";
var ex = context.Features.Get<IExceptionHandlerFeature>();
if (ex != null)
{
var err = $"<h1>Error: {ex.Error.Message}</h1>{ex.Error.StackTrace }";
await context.Response.WriteAsync(err).ConfigureAwait(false);
}
});
}
);
There are also more details on the IExceptionFilter
approach, but I won't repeat all of that here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With