Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core equivalent of ASP.NET MVC 5's HttpException

In ASP.NET MVC 5 you could throw a HttpException with a HTTP code and this would set the response like so:

throw new HttpException((int)HttpStatusCode.BadRequest, "Bad Request."); 

HttpException does not exist in ASP.NET Core. What is the equivalent code?

like image 306
Muhammad Rehan Saeed Avatar asked Jun 25 '15 15:06

Muhammad Rehan Saeed


People also ask

Is .NET Core and MVC core same?

The main difference between ASP.NET Core and ASP.NET MVC 5 is their cross-platform approach. ASP.NET Core can be used on Windows, Mac, or Linux, whereas ASP.NET MVC 5 can only be used for applications on Windows. The ASP.NET Core MVC is a framework for building web apps and APIs, optimized for use with ASP.NET Core.

Is ASP.NET Core the same as .NET 5?

ASP.NET Core 5.0 is based on . NET 5 but retains the name "Core" to avoid confusing it with ASP.NET MVC 5. Likewise, Entity Framework Core 5.0 retains the name "Core" to avoid confusing it with Entity Framework 5 and 6.

Is there MVC in .NET Core?

The ASP.NET Core MVC framework is a lightweight, open source, highly testable presentation framework optimized for use with ASP.NET Core. ASP.NET Core MVC provides a patterns-based way to build dynamic websites that enables a clean separation of concerns.

Is ASP.NET MVC 5 outdated?

Is the framework outdated? ASP.NET MVC is no longer in active development. The last version update was in November 2018. Despite this, a lot of projects are using ASP.NET MVC for web solution development.


2 Answers

I implemented my own HttpException and supporting middleware which catches all HttpException's and turns them into the corresponding error response. A short extract can be seen below. You can also use the Boxed.AspNetCore Nuget package.

Usage Example in Startup.cs

public void Configure(IApplicationBuilder application) {     application.UseIISPlatformHandler();      application.UseStatusCodePagesWithReExecute("/error/{0}");     application.UseHttpException();      application.UseMvc(); } 

Extension Method

public static class ApplicationBuilderExtensions {     public static IApplicationBuilder UseHttpException(this IApplicationBuilder application)     {         return application.UseMiddleware<HttpExceptionMiddleware>();     } } 

Middleware

internal class HttpExceptionMiddleware {     private readonly RequestDelegate next;      public HttpExceptionMiddleware(RequestDelegate next)     {         this.next = next;     }      public async Task Invoke(HttpContext context)     {         try         {             await this.next.Invoke(context);         }         catch (HttpException httpException)         {             context.Response.StatusCode = httpException.StatusCode;             var responseFeature = context.Features.Get<IHttpResponseFeature>();             responseFeature.ReasonPhrase = httpException.Message;         }     } } 

HttpException

public class HttpException : Exception {     private readonly int httpStatusCode;      public HttpException(int httpStatusCode)     {         this.httpStatusCode = httpStatusCode;     }      public HttpException(HttpStatusCode httpStatusCode)     {         this.httpStatusCode = (int)httpStatusCode;     }      public HttpException(int httpStatusCode, string message) : base(message)     {         this.httpStatusCode = httpStatusCode;     }      public HttpException(HttpStatusCode httpStatusCode, string message) : base(message)     {         this.httpStatusCode = (int)httpStatusCode;     }      public HttpException(int httpStatusCode, string message, Exception inner) : base(message, inner)     {         this.httpStatusCode = httpStatusCode;     }      public HttpException(HttpStatusCode httpStatusCode, string message, Exception inner) : base(message, inner)     {         this.httpStatusCode = (int)httpStatusCode;     }      public int StatusCode { get { return this.httpStatusCode; } } } 

In the long term, I would advise against using exceptions for returning errors. Exceptions are slower than just returning an error from a method.

like image 124
Muhammad Rehan Saeed Avatar answered Sep 27 '22 20:09

Muhammad Rehan Saeed


After a brief chat with @davidfowl, it seems that ASP.NET 5 has no such notion of HttpException or HttpResponseException that "magically" turn to response messages.

What you can do, is hook into the ASP.NET 5 pipeline via MiddleWare, and create one that handles the exceptions for you.

Here is an example from the source code of their error handler middleware which will set the response status code to 500 in case of an exception further up the pipeline:

public class ErrorHandlerMiddleware {     private readonly RequestDelegate _next;     private readonly ErrorHandlerOptions _options;     private readonly ILogger _logger;      public ErrorHandlerMiddleware(RequestDelegate next,                                    ILoggerFactory loggerFactory,                                   ErrorHandlerOptions options)     {         _next = next;         _options = options;         _logger = loggerFactory.CreateLogger<ErrorHandlerMiddleware>();         if (_options.ErrorHandler == null)         {             _options.ErrorHandler = _next;         }     }      public async Task Invoke(HttpContext context)     {         try         {             await _next(context);         }         catch (Exception ex)         {             _logger.LogError("An unhandled exception has occurred: " + ex.Message, ex);              if (context.Response.HasStarted)             {                 _logger.LogWarning("The response has already started,                                      the error handler will not be executed.");                 throw;             }              PathString originalPath = context.Request.Path;             if (_options.ErrorHandlingPath.HasValue)             {                 context.Request.Path = _options.ErrorHandlingPath;             }             try             {                 var errorHandlerFeature = new ErrorHandlerFeature()                 {                     Error = ex,                 };                 context.SetFeature<IErrorHandlerFeature>(errorHandlerFeature);                 context.Response.StatusCode = 500;                 context.Response.Headers.Clear();                  await _options.ErrorHandler(context);                 return;             }             catch (Exception ex2)             {                 _logger.LogError("An exception was thrown attempting                                   to execute the error handler.", ex2);             }             finally             {                 context.Request.Path = originalPath;             }              throw; // Re-throw the original if we couldn't handle it         }     } } 

And you need to register it with StartUp.cs:

public class Startup {     public void Configure(IApplicationBuilder app,                            IHostingEnvironment env,                            ILoggerFactory loggerfactory)     {        app.UseMiddleWare<ExceptionHandlerMiddleware>();     } } 
like image 29
Yuval Itzchakov Avatar answered Sep 27 '22 20:09

Yuval Itzchakov