Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the global exception handling method of ASP.NET Core

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

Most people do not understand the knowledge points of this article "what is the ASP.NET Core global exception handling method?", so the editor summarizes the following content, detailed content, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "what is the ASP.NET Core global exception handling method" article.

I. Preface

In program design, we will encounter a variety of exception problems, a good exception handling solution can help developers quickly locate the problem, but also give users a better user experience. So how do we catch and handle exceptions in AspNetCore? Let's take an WebApi project as an example to show how to catch and handle exceptions.

Exception handling 1. Exception handling

Anyone who has developed an ASP.NET program knows that: IExceptionFilter. This filter can also be used in AspNetCore to catch exceptions. However, for IExceptionFilter, it is more recommended to use its asynchronous version: IAsyncExceptionFilter. So how do you use the filter? Let's take IAsyncExceptionFilter as an example, which is the same for synchronous versions.

We add a Model folder to the project to store the returned entity class, where a generic class is defined:

Using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;namespace ExceptionDemo.Model {public class ResultModel {/ return result Encoding 0: failure 1: success / public int ResultCode {get; set } / returned result content succeeded: Success failed: exception content / public string ResultMsg {get; set;} / returned result succeeded: failed to return T type data: default null / public T ResultData {get; set;}

We add a Filter folder to the project under which all the filters are placed. Then add a class: CustomerExceptionFilter, and make it inherit from IAsyncExceptionFilter. The code is as follows:

Using ExceptionDemo.Model;using Microsoft.AspNetCore.Http;using Microsoft.AspNetCore.Mvc;using Microsoft.AspNetCore.Mvc.Filters;using Newtonsoft.Json;using System.Threading.Tasks Namespace ExceptionDemo.Filter {/ Custom exception filter / public class CustomerExceptionFilter: IAsyncExceptionFilter {/ override the OnExceptionAsync method Define your own processing logic / public Task OnExceptionAsync (ExceptionContext context) {/ / handle if the exception is not handled if (context.ExceptionHandled==false) {/ / define the return type var result = new ResultModel {ResultCode = 0 ResultMsg = context.Exception.Message} Context.Result = new ContentResult {/ / return status code is set to 200, indicating success StatusCode = StatusCodes.Status200OK, / / setting the return format ContentType= "application/json" Charset=utf-8 ", Content=JsonConvert.SerializeObject (result)};} / / is set to true, indicating that the exception has been handled context.ExceptionHandled = true; return Task.CompletedTask;}}

The above code is very simple. We create a new custom exception filter, then define our own handling logic in the OnExceptionAsync method, and still let http return the status code 200 after the error is reported, and return the error message to the client.

Then add a controller, named ExceptionFilter, to simulate the exception in the controller:

Using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using ExceptionDemo.Model;using Microsoft.AspNetCore.Http;using Microsoft.AspNetCore.Mvc;namespace ExceptionDemo.Controllers {[Route ("api/ [controller]")] [ApiController] public class ExceptionFilterController: ControllerBase {[HttpGet] public async Task Get () {int I = 0; int k = 10 / / there will be an exception int j = await Task.Run (() = > {return k / I;}); return new ResultModel () {ResultCode=1, ResultMsg= "Success", ResultData=j};}

Finally, we need to inject the custom exception filter. Here, we choose to use global injection in the ConfigureServices method of the Startup class:

Services.AddControllers (options = > {options.Filters.Add (new CustomerExceptionFilter ());})

Then run the program to see the results:

If we do not use the filter to catch and handle exceptions, we will get an internal error with a Http status code of 500. this error is not convenient to locate the problem, and the information returned to the client is not friendly enough. Using a filter to handle exceptions will be friendly after special handling.

In the above custom filter code, there is the following line of code:

Context.ExceptionHandled = true

Note: this code is critical, when you finish handling the exception, be sure to change this property to true, indicating that the exception has been handled, so that the exception will not be handled elsewhere.

2. Use middleware to handle exceptions

We know that AspNetCore's pipeline model has the characteristics of layer-by-layer transmission, so we can achieve global exception capture in the pipeline. We create a new custom exception middleware:

Using Microsoft.AspNetCore.Http;using Microsoft.AspNetCore.Mvc;using System;using System.Text.Json;using System.Threading.Tasks;namespace ExceptionDemo.Middleware {/ custom exception middleware / public class CustomerExceptionMiddleware {/ delegate / private readonly RequestDelegate _ next; public CustomerExceptionMiddleware (RequestDelegate next) {_ next = next } public async Task Invoke (HttpContext context) {try {await _ next (context);} catch (Exception ex) {context.Response.ContentType = "application/problem+json"; var title = "An error occured:" + ex.Message Var details = ex.ToString (); var problem = new ProblemDetails {Status = 200, Title = title, Detail = details}; var stream = context.Response.Body; await JsonSerializer.SerializeAsync (stream, problem) }

Then create a new extension method:

Using Microsoft.AspNetCore.Builder;namespace ExceptionDemo.Middleware {/ static class / public static class ExceptionMiddlewareExtension {/ static method / the type to be extended is public static void UseExceptionMiddleware (this IApplicationBuilder app) {app.UseMiddleware (typeof (CustomerExceptionMiddleware));}

Finally, use the custom exception middleware in the Configure method of the Startup class:

App.UseExceptionMiddleware ()

Then we comment out the exception filter registered above and run the program to access it:

Exceptions can also be caught this way.

3. Use the framework to bring exception middleware

Let's first look at the following code:

If (env.IsDevelopment ()) {app.UseDeveloperExceptionPage ();}

This code will be seen when we create a WebApi project using AspNetCore. If you create a MVC project, it is the following code:

If (env.IsDevelopment ()) {app.UseDeveloperExceptionPage ();} else {app.UseExceptionHandler ("/ Error");}

The purpose of these two pieces of code is to catch and handle exceptions and is the first middleware to be added to the pipeline.

The meaning of UseDeveloperExceptionPage is easy to understand: for development mode, once an error is reported, jump to the error stack page. The second UseExceptionHandler is also interesting, and we can roughly guess from its name that it must be an error interceptor. So what's the difference between it and the above custom exception handling middleware?

UseExceptionHandler is actually the default error handling. It is actually a middleware, and its original name is ExceptionHandlerMiddleware. When using the UseExceptionHandler method, we can optionally fill in various parameters. For example, the second section of the code above, filled in the "/ Error" parameter, indicates that when an exception occurs, it will be located to the corresponding path, where the located page is "http://localhost:5001/Error"". This is an error page that comes with MVC. Of course, you can also specify a page that you define.

UseExceptionHandler also has an extension method to specify the ExceptionHandlerOptions parameter, which is an important parameter for ExceptionHandlerMiddleware middleware:

The parameter name indicates the path of ExceptionHandlingPath redirection. For example, the "/ Error" just now is actually the specified parameter ExceptionHandler error interceptor handler.

ExceptionHandler allows us to specify our own exception handling logic within ExceptionHandlerMiddleware. The type of this parameter is a delegate of type RequestDelegate. Therefore, UseExceptionHandler provides an easy way to write it, which allows us to create a custom error interception pipeline in ExceptionHandlerMiddleware to handle exceptions:

Using System;using System.Collections.Generic;using System.Linq;using System.Text.Json;using System.Threading.Tasks;using ExceptionDemo.Filter;using ExceptionDemo.Middleware;using Microsoft.AspNetCore.Builder;using Microsoft.AspNetCore.Diagnostics;using Microsoft.AspNetCore.Hosting;using Microsoft.AspNetCore.Http;using Microsoft.AspNetCore.Mvc;using Microsoft.Extensions.Configuration;using Microsoft.Extensions.DependencyInjection;using Microsoft.Extensions.Hosting;using Microsoft.Extensions.Logging Namespace ExceptionDemo {public class Startup {public Startup (IConfiguration configuration) {Configuration = configuration;} public IConfiguration Configuration {get;} / / This method gets called by the runtime. Use this method to add services to the container. Public void ConfigureServices (IServiceCollection services) {# region registers the global exception filter / / services.AddControllers (options = > / {/ / options.Filters.Add (new CustomerExceptionFilter ()); / /}); # endregion services.AddControllers ();} / / This method gets called by the runtime. Use this method to configure the HTTP request pipeline. Public void Configure (IApplicationBuilder app, IWebHostEnvironment env) {if (env.IsDevelopment ()) {app.UseDeveloperExceptionPage ();} else {app.UseExceptionHandler (builder = > builder.Use (ExceptionHandlerDemo));} app.UseExceptionMiddleware (); app.UseRouting () App.UseAuthorization (); app.UseEndpoints (endpoints = > {endpoints.MapControllers ();});} private async Task ExceptionHandlerDemo (HttpContext httpContext,Func next) {/ / this information is provided by the ExceptionHandlerMiddleware middleware and contains the exception information captured by the ExceptionHandlerMiddleware middleware. Var exceptionDetails = httpContext.Features.Get (); var ex = exceptionDetails?.Error; if (ex! = null) {httpContext.Response.ContentType = "application/problem+json"; var title = "An error occured:" + ex.Message; var details = ex.ToString () Var problem = new ProblemDetails {Status = 500, Title = title, Detail = details}; var stream = httpContext.Response.Body; await JsonSerializer.SerializeAsync (stream, problem) Comparison between Middleware and filter

In the above example, we use middleware and filters to handle exceptions, so what's the difference between middleware and filters? The difference between the two: the difference in interception scope.

As a filter, IExceptionFilter needs to submit error information to it for processing after the controller finds an error, so its exception handling range is within the controller. If we want to catch some errors before entering the controller, IExceptionFilter cannot catch them. It is easy for ExceptionHandlerMiddleware exception middleware, which is added to the pipeline as the first middleware, and any exceptions that occur after it can be caught.

So why are there two ways of handling exceptions? Is it not possible to use only ExceptionHandlerMiddleware middleware to handle exceptions? It can catch exceptions that occur at any time, so why should there be a filter? If you want to catch and handle exceptions quickly when an exception occurs in the controller, it is a good choice to use a filter to handle the exception. If an exception occurs within the controller, the exception is first caught by the filter and finally caught by the middleware.

When we customize the filter, we have this code: context.ExceptionHandled = true; if the exception is marked as handled in the custom filter, the first exception handling middleware will assume that there is no error and will not enter the handling logic. Therefore, if the ExceptionHandled property is not set to true, the exception handling result may be overwritten.

The above is the content of this article on "what is the global exception handling method of ASP.NET Core". I believe we all have a certain understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report