Custom ASP.NET CORE learning exception handling

Original: Custom ASP.NET CORE learning exception handling

Why choose exception handling middleware?

Traditional ASP.NET exception filter can be used in abnormal manner, in the CORE ASP.NET, the pipes are connected in the form of a plurality of intermediate processing request, but the five common filter is retained, may also be employed exception filter to handle exceptions, but the exception filter can not handle the exception than the MVC middleware, in order to unify the overall consideration, the use of middleware to handle exceptions more appropriate

 

Why choose custom exception middleware?

 Let's look at three ASP.NET CORE built-in exception handling middleware DeveloperExceptionPageMiddleware, ExceptionHandlerMiddleware, StatusCodePagesMiddleware 

1.DeveloperExceptionPageMiddleware 
 can be given in detail of the request / back / error message, because it contains sensitive information, it is only suitable for the development environment

2.ExceptionHandlerMiddleware (Chiang God blog  http://www.cnblogs.com/artech/p/error-handling-in-asp-net-core-3.html )

Only 500 error handling

3.StatusCodePagesMiddleware (Chiang God blog  http://www.cnblogs.com/artech/p/error-handling-in-asp-net-core-4.html )

Handles the error between 400-599, but need not contain content Response (ContentLength = 0 && ContentType = null, the experiment can not respond in mvc uncaught exception)

Because of their limitations ExceptionHandlerMiddleware and StatusCodePagesMiddleware, both of which need to use with. In contrast custom middleware is more flexible, which would work on various error states unified treatment, treatment can be decided according to the configuration.

 

CustomExceptionMiddleWare

At the outset exception middleware configuration class

 1     /// <summary>
 2     /// 异常中间件配置对象
 3     /// </summary>
 4     public class CustomExceptionMiddleWareOption
 5     {
 6         public CustomExceptionMiddleWareOption(
 7             CustomExceptionHandleType handleType = CustomExceptionHandleType.JsonHandle,
 8             IList<PathString> jsonHandleUrlKeys = null,
 9             string errorHandingPath = "")
10         {
11             HandleType = handleType;
12             = JsonHandleUrlKeys jsonHandleUrlKeys;
 13 is              ErrorHandingPath = errorHandingPath;
 14          }
 15  
16          ///  <Summary> 
. 17          /// Exception handling
 18 is          ///  </ Summary> 
. 19          public CustomExceptionHandleType The HandleType { GET ; SET ;}
 20 is  
21 is          ///  < Summary> 
22 is          /// the Url Json processing mode key
 23 is          ///  <para> take effect only when = Both the HandleType </ para> 
24          ///  </ Summary> 
25          publicThe IList <PathString> JsonHandleUrlKeys { GET ; SET ;}
 26 is  
27          ///  <Summary> 
28          /// error jump page
 29          ///  </ Summary> 
30          public PathString ErrorHandingPath { GET ; SET ;}
 31 is      }
 32  
33 is      / //  <Summary> 
34 is      /// error handling
 35      ///  </ Summary> 
36      public  enum CustomExceptionHandleType
 37 [      {
 38 is          JsonHandle = 0 ,   // Json form processing 
39          PageHandle = . 1 ,    // skip processing page 
40          Both = 2           // automatic processing in accordance with the keyword Url 
41      }

Member of the unusual statement middleware

        ///  <Summary> 
        /// conduit delegate requests
         ///  </ Summary> 
        Private RequestDelegate -next; 

        ///  <Summary> 
        /// configuration object
         ///  </ Summary> 
        Private CustomExceptionMiddleWareOption _option; 

        ///  <Summary > 
        /// status code dictionary in need of treatment
         ///  </ Summary> 
        Private the IDictionary < int , String > exceptionStatusCodeDic; 

        public CustomExceptionMiddleWare (RequestDelegate Next, CustomExceptionMiddleWareOption Option) 
        { 
            -next = Next;
            _option = Option; 
            exceptionStatusCodeDic = new new the Dictionary < int , String > 
            { 
                { 401 , " unauthorized request " }, 
                { 404 , " can not find the page " }, 
                { 403 , " access denied " }, 
                { 500 , " An unexpected server error has occurred " }
                 // rest of the state of self-expansion 
             };
        }

The main exception middleware logic

. 1          public  the async the Task the Invoke (the HttpContext context)
 2          {
 . 3              Exception Exception = null ;
 . 4              the try 
. 5              {
 . 6                  the await -next (context);    // call to perform a lower duct intermediate piece 
. 7              }
 . 8              the catch (Exception EX)
 . 9              {
 10                  context. Response.Clear ();    
 . 11                  context.Response.StatusCode = 500 ;    // uncaught exception occurs, the manual state code 
12 is                  exception = EX;
13             }
14             finally
15             {
16                 if (exceptionStatusCodeDic.ContainsKey(context.Response.StatusCode) && 
17                     !context.Items.ContainsKey("ExceptionHandled"))  //预处理标记
18                 {
19                     var errorMsg = string.Empty;
20                     if (context.Response.StatusCode == 500 && exception != null)
21                     {
22                         errorMsg = $"{exceptionStatusCodeDic[context.Response.StatusCode]}\r\n{(exception.InnerException != null ? exception.InnerException.Message : exception.Message)}";
23                     }
24                     else
25                     {
26                         errorMsg = exceptionStatusCodeDic[context.Response.StatusCode];
27                     }
28                     exception = new Exception(errorMsg);
29                 }
30 
31                 if (exception != null)
32                 {
33                     var= HandleType _option.HandleType;
 34 is                      IF (HandleType == CustomExceptionHandleType.Both)    // determines According exception handling Url keyword 
35                      {
 36                          var requestPath = context.Request.Path;
 37 [                          HandleType = _option.JsonHandleUrlKeys =! null && _option. JsonHandleUrlKeys.Count (
 38 is                              K => requestPath.StartsWithSegments (K, StringComparison.CurrentCultureIgnoreCase))> 0 ?
 39                              CustomExceptionHandleType.JsonHandle:
 40                             CustomExceptionHandleType.PageHandle;
41                     }
42                     
43                     if (handleType == CustomExceptionHandleType.JsonHandle)
44                         await JsonHandle(context, exception);
45                     else
46                         await PageHandle(context, exception, _option.ErrorHandingPath);
47                 }
48             }
49         }
50 
51         /// <summary>
52         /// 统一格式响应类
53         /// </summary>
54         /// <param name="ex"></param>
55         /// <returns></returns>
56         private ApiResponse GetApiResponse(Exception ex)
57         {
58             return new ApiResponse() { IsSuccess = false, Message = ex.Message };
59         }
60 
61         /// <summary>
62         /// 处理方式:返回Json格式
63         /// </summary>
64         /// <param name="context"></param>
65         /// <param name="ex"></param>
66         /// <returns></returns>
67         private async Task JsonHandle(HttpContext context, Exception ex)
68         {
69             var apiResponse = GetApiResponse(ex);
70             var serialzeStr = JsonConvert.SerializeObject(apiResponse);
71             context.Response.ContentType = "application/json";
72             await context.Response.WriteAsync(serialzeStr, Encoding.UTF8);
73         }
74 
75         /// <summary>
76         /// 处理方式:跳转网页
77         /// </summary>
78         /// <param name="context"></param>
79         /// <param name="ex"></param>
80         /// <param name="path"></param>
81         /// <returns></returns>
82         private async Task PageHandle(HttpContext context, Exception ex, PathString path)
83         {
84             context.Items.Add("Exception", ex);
85             var originPath = context.Request.Path;
86             context.Request.Path = path;   -next (context);      
the await89            {
88the try87set the requested page to jump to an error page//
             
                  90              }
 91 is              the catch {}
 92              the finally 
93              {
 94                  context.Request.Path = originPath;    // restore the originally requested page 
95              }
 96          }

Extended use of middleware classes registered

1  public static class CustomExceptionMiddleWareExtensions
2     {
3 
4         public static IApplicationBuilder UseCustomException(this IApplicationBuilder app, CustomExceptionMiddleWareOption option)
5         {
6             return app.UseMiddleware<CustomExceptionMiddleWare>(option);
7         }
8     }

Sign exception middleware in Configuref method of Startup.cs

. 1    app.UseCustomException ( new new CustomExceptionMiddleWareOption (
 2                      HandleType: CustomExceptionHandleType.Both,   // The url keyword determination processing mode 
. 3                      jsonHandleUrlKeys: new new PathString [] { " / API " },
 . 4                      errorHandingPath: " / Home / error " ));

 

Next we capture without exception to be tested, first to simulate a page will be jump

 

The results access / home / about the

 

Access / home / test results (the address does not exist)

 

OK way abnormal jump page of the test is completed, then we test the Exception Handling returns unified format (json), also a first analog anomalies are not captured

 

The results Access / api / token / gettesterror of

 

Access / api / token / test results (the address does not exist)

 

Access / api / token / getvalue results (the interface requires authentication)

 

The test is completed, the page jumps and unified format returned no problems, custom exception middleware has worked as expected

Note that the custom HTTP response to each middleware would request, processing logic must be streamlined to prevent unnecessary performance issues

Guess you like

Origin www.cnblogs.com/lonelyxmas/p/10965635.html
Recommended