Asp.Net Core Web Api global exception middleware

Middleware can handle exceptions acquisition system abnormalities

1, add exception handling middleware AppExceptionHandlerMiddleware

  public class AppExceptionHandlerMiddleware
    {
        private readonly RequestDelegate _next;
        private AppExceptionHandlerOption _option = new AppExceptionHandlerOption();
        private readonly IDictionary<int, string> _exceptionStatusCodeDic;
        private readonly ILogger<AppExceptionHandlerMiddleware> _logger;
        public AppExceptionHandlerMiddleware(RequestDelegate next, Action<AppExceptionHandlerOption> actionOptions, ILogger<AppExceptionHandlerMiddleware> logger)
        {
            -next = Next; 
            _logger = Logger; 
            actionOptions (_option); 
            _exceptionStatusCodeDic = new new the Dictionary < int , String > 
            { 
                { 401 , " unauthorized request " }, 
                { 404 , " can not find the page " }, 
                { 403 , " access is denied " }, 
                { 500 , " the server unexpected error has occurred" }
            }; 
        } 

        Public  the async the Task the Invoke (the HttpContext context) 
        { 
            Exception Exception = null ;
             the try 
            { 
                the await -next (context); // next pipe for a middleware calls 
            }
             the catch (AppException EX) 
            { 
                context.Response.StatusCode = StatusCodes.Status200OK ;
                 var apiResponse = new new ApiResponse () = {isSuccess to false , the Message = ex.ErrorMsg};
                 var serializerResult = JsonConvert.SerializeObject(apiResponse);
                context.Response.ContentType = "application/json;charset=utf-8";
                await context.Response.WriteAsync(serializerResult);
            }
            catch (Exception ex)
            {
                context.Response.Clear();
                context.Response.StatusCode = StatusCodes.Status500InternalServerError; //发生未捕获的异常,手动设置状态码
                exception = ex;
            }
            finally
            {
                if (_exceptionStatusCodeDic.ContainsKey(context.Response.StatusCode) && !context.Items.ContainsKey("ExceptionHandled")) //预处理标记
                {
                    string errorMsg;
                    if (context.Response.StatusCode == 500 && exception != null)
                    {
                        errorMsg = $"{(exception.InnerException != null ? exception.InnerException.Message : exception.Message)}";
                        _logger.LogError(errorMsg);
                    }
                    else
                    { 
                        ErrorMsg = _exceptionStatusCodeDic [context.Response.StatusCode]; 
                    } 
                    Exception = new new Exception (errorMsg); 
                } 
                IF (Exception =! Null ) 
                { 
                    var HandleType = _option.HandleType;
                     IF (HandleType == AppExceptionHandleType.Both) // The Url exception handling determined keywords 
                    {
                         var requestPath = context.Request.Path; 
                        HandleType= _option.JsonHandleUrlKeys != null && _option.JsonHandleUrlKeys.Count(
                                         k => requestPath.StartsWithSegments(k, StringComparison.CurrentCultureIgnoreCase)) > 0
                            ? AppExceptionHandleType.JsonHandle
                            : AppExceptionHandleType.PageHandle;
                    }
                    if (handleType == AppExceptionHandleType.JsonHandle)
                        await JsonHandle(context, exception);
                    else
                        await PageHandle(context, exception, _option.ErrorHandingPath);
                }
            }
        }

        ///  <Summary> 
        /// uniform format response class
         ///  </ Summary> 
        ///  <param name = "EX"> </ param> 
        ///  <Returns> </ Returns> 
        Private ApiResponse GetApiResponse (Exception EX) 
        { 
            return  new new ApiResponse () = {isSuccess to false , the Message = ex.Message}; 
        } 

        ///  <Summary> 
        /// treatment: return Json format
         ///  </ Summary> 
        ///  <param name = "context"> </ param> 
        ///  <param name = "EX"> </ param> 
        ///  <Returns> </ Returns>
        private async Task JsonHandle(HttpContext context, System.Exception ex)
        {
            var apiResponse = GetApiResponse(ex);
            var serializerResult = JsonConvert.SerializeObject(apiResponse);
            context.Response.ContentType = "application/json;charset=utf-8";
            await context.Response.WriteAsync(serializerResult);
        }

        /// <summary>
        /// 处理方式:跳转网页
        /// </summary>
        /// <param name="context"></param>
        /// <param name="ex"></param>
        /// <param name="path"></param>
        ///  <Returns> </ Returns> 
        Private  the async the Task PageHandle (the HttpContext context, System.Exception EX, PathString path) 
        { 
            context.Items.Add ( " Exception " , EX);
             var originPath = context.Request.Path; 
            context .Request.Path = path;    // set page request page to jump to an error 
            the try 
            { 
                the await -next (context); 
            } 
            the catch 
            { 

            } 
            the finally 
            { 
                context.Request.Path = originPath;    //Restore the original request page 
            } 
        } 
    }

2, exception handling was added configuration item AppExceptionHandlerOption

 public class AppExceptionHandlerOption
    {
        public AppExceptionHandlerOption(
            AppExceptionHandleType handleType = AppExceptionHandleType.JsonHandle,
            IList<PathString> jsonHandleUrlKeys = null,
            string errorHandingPath = "")
        {
            HandleType = handleType;
            JsonHandleUrlKeys = jsonHandleUrlKeys;
            ErrorHandingPath = errorHandingPath;
        }

        /// <summary>
        ///Exception handling
         ///  </ Summary> 
        public AppExceptionHandleType The HandleType { GET ; SET ;} 

        ///  <Summary> 
        /// the Url keyword Json processing mode
         ///  <para> take effect only when = Both The HandleType </ para > 
        ///  </ Summary> 
        public the IList <PathString> JsonHandleUrlKeys { GET ; SET ;} 

        ///  <Summary> 
        /// error jump page
         ///  </ Summary> 
        public PathString ErrorHandingPath { GET ; SET ;} 
    }

3, error handling scheme

  ///  <Summary> 
    /// error handling
     ///  </ Summary> 
    public  enum AppExceptionHandleType 
    { 
        JsonHandle = 0 ,    // Json form processing 
        PageHandle = . 1 ,    // skip processing a web page 
        Both = 2           // The key Url automatic word processing 
    }

4, the corresponding structures

 public class ApiResponse
    {
        public int State => IsSuccess ? 1 : 0;
        public bool IsSuccess { get; set; }
        public string Message { get; set; }
    }

5, extension

  public static class AppExceptionHandlerExtensions
    {
        public static IApplicationBuilder UserAppExceptionHandler(this IApplicationBuilder app, Action<AppExceptionHandlerOption> options)
        {
            return app.UseMiddleware<AppExceptionHandlerMiddleware>(options);
        }

    }

 6, a custom exception type

 public class AppException:Exception
    {
        public string ErrorMsg { get; set; }
        public AppException(string errorMsg)
        {
            ErrorMsg = errorMsg;
        }
    }

 

Guess you like

Origin www.cnblogs.com/caowb/p/11976885.html