Blogs Hub

by AskGif | Nov 28, 2018 | Category :coding

Exception Handling in ASP.NET Core Web API

Exception Handling in ASP.NET Core Web API

<p>Question:</p> <p>I started using ASP.NET Core for my new REST API project after using regular ASP.NET Web API for many years. I don't see a good way to handle exceptions in ASP.NET Core Web API. I tried to implement exception handling filter/attribute:</p> <pre class="language-csharp"><code>public class ErrorHandlingFilter : ExceptionFilterAttribute { public override void OnException(ExceptionContext context) { HandleExceptionAsync(context); context.ExceptionHandled = true; } private static void HandleExceptionAsync(ExceptionContext context) { var exception = context.Exception; if (exception is MyNotFoundException) SetExceptionResult(context, exception, HttpStatusCode.NotFound); else if (exception is MyUnauthorizedException) SetExceptionResult(context, exception, HttpStatusCode.Unauthorized); else if (exception is MyException) SetExceptionResult(context, exception, HttpStatusCode.BadRequest); else SetExceptionResult(context, exception, HttpStatusCode.InternalServerError); } private static void SetExceptionResult( ExceptionContext context, Exception exception, HttpStatusCode code) { context.Result = new JsonResult(new ApiResponse(exception)) { StatusCode = (int)code }; } }</code></pre> <p><span style="color: #242729; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px;">And here is my Startup filter registration:</span></p> <pre class="language-csharp"><code>services.AddMvc(options =&gt; { options.Filters.Add(new AuthorizationFilter()); options.Filters.Add(new ErrorHandlingFilter()); });</code></pre> <p>The issue I was having is that when exception occurred in my AuthorizationFilter it's not being handled by ErrorHandlingFilter. I was expecting it to be caught there just like it worked with old ASP.NET Web API.</p> <p>&nbsp;</p> <p>So how can I catch all application exceptions as well as any exceptions from Action Filters?</p> <p>&nbsp;</p> <p>Solution:</p> <p>&nbsp;</p> <p>Exception Handling Middleware</p> <p>After many experiments with different exception handling approaches I ended up using middleware. It worked the best for my ASP.NET Core Web API application. It handles application exceptions as well as exceptions from filters and I have full control over exception handling and creating a response json. Here is my exception handling middleware:</p> <pre class="language-csharp"><code>public class ErrorHandlingMiddleware { private readonly RequestDelegate next; public ErrorHandlingMiddleware(RequestDelegate next) { this.next = next; } public async Task Invoke(HttpContext context /* other dependencies */) { try { await next(context); } catch (Exception ex) { await HandleExceptionAsync(context, ex); } } private static Task HandleExceptionAsync(HttpContext context, Exception exception) { var code = HttpStatusCode.InternalServerError; // 500 if unexpected if (exception is MyNotFoundException) code = HttpStatusCode.NotFound; else if (exception is MyUnauthorizedException) code = HttpStatusCode.Unauthorized; else if (exception is MyException) code = HttpStatusCode.BadRequest; var result = JsonConvert.SerializeObject(new { error = exception.Message }); context.Response.ContentType = "application/json"; context.Response.StatusCode = (int)code; return context.Response.WriteAsync(result); } }</code></pre> <p>Register it before MVC in Startup class:</p> <pre class="language-csharp"><code>app.UseMiddleware(typeof(ErrorHandlingMiddleware)); app.UseMvc();</code></pre> <p>Here is an example of exception response:</p> <pre class="language-csharp"><code>{ "error": "Authentication token is not valid." }</code></pre> <p>You can add stack trace, exception type name, error codes or anything you want to it. Very flexible.</p>

read more...