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; } }