Asp.net Core 異常日志與API返回值處理


需求:

1、對異常進行捕獲記錄日志 並且修改返回值給前端

 

解釋:

ILogger4是自定義的一個日志,更改它就好

 

解決方案1:

使用中間件進行異常捕獲並且修改其返回值

 public class ErrorMiddleware
    {
        private readonly RequestDelegate _next;
        ILogger4<ErrorMiddleware> logger4;
        public ErrorMiddleware(RequestDelegate next,ILogger4<ErrorMiddleware> logger4)
        {
            _next = next;
            this.logger4 = logger4;
        }

        public async Task Invoke(HttpContext httpContext)
        {
            try
            {
                await _next(httpContext);
            }
            catch (Exception e)
            {
                logger4.LogError(e,e.Message+"\r\n"+e.StackTrace);
                throw e;
            }
        
          
        }
    }

這一步簡單,從源碼里 ExceptionHandlerMiddleware.cs類里 Copy的代碼

使用中間件進行修改返回值

 public class ResultMiddleware
    {
        private readonly RequestDelegate _next;

        public ResultMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext httpContext)
        {

            await _next(httpContext);
string bodyString = "<p>不好意思 系統正在升級維護 請稍后再試</p>";
var by = Encoding.UTF8.GetBytes(bodyString);
var heard =(Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseHeaders)httpContext.Response.Headers; heard.HeaderContentLength = by.Length.ToString();
//必須要手動設置請求頭的ContentLength大小 才能修改返回值的數據 await httpContext.Response.Body.WriteAsync(by);
        }
    }

這是從網上copy 修改的代碼,不推薦使用 開銷太大 轉為過濾器

 

解決方案2:

使用中間件進行異常捕獲並且修改其返回值

異常過濾器

 /// <summary>
    /// 異常過濾器
    /// </summary>
    public class ErrorFilter :Attribute,IExceptionFilter
    {

        ILogger4<ErrorFilter> logger4;
        /// <summary>
        /// 標簽
        /// </summary>
        public ErrorFilter() {
        }

        /// <summary>
        /// 全局配置
        /// </summary>
        /// <param name="logger4"></param>
        public ErrorFilter(ILogger4<ErrorFilter> logger4) {
            this.logger4 = logger4;
        }

        public void OnException(ExceptionContext context)
        {
            var e = context.Exception;
            logger4.LogError(e, e.Message + "\r\n" + e.StackTrace);
            context.Result = new JsonResult(new BaseResult(e.Message));
        }
    }

 

方法過濾器

  /// <summary>
    /// 對打上該標記的 返回結果為JsonResult的請求進行Result包裝
    /// </summary>
    public class ApiResultFilter : Attribute, IActionFilter
    {
        /// <summary>
        /// 執行方法體之后
        /// </summary>
        /// <param name="context"></param>
        public void OnActionExecuted(ActionExecutedContext context)
        {
            
            var result = context.Result;
            if (result!=null &&result is JsonResult resulta)
            {
                context.Result = new JsonResult(new BaseResult(resulta.Value));
            }
           
        }

        /// <summary>
        /// 執行方法體之前
        /// </summary>
        /// <param name="context"></param>
        public void OnActionExecuting(ActionExecutingContext context)
        {
            //不做修改
        }
    }

 

可以使用標簽的方法

 /// <summary>
        /// 測試 返回過濾器
        /// </summary>
        /// <returns></returns>
        [ErrorFilter]
        [ApiResultFilter]
        [HttpGet]
        public IActionResult TestReuslt()
        {
            throw new Exception("AA");
            var obj = new
            {
                A = "321"
            };
            return Json(obj);
        }

 

 

也可以使用全局配置的方法

//注冊過濾器
            services.AddSingleton<ApiResultFilter>();
            services.AddSingleton<ErrorFilter>();
            
            services.AddMvc(
                config => {
                    config.Filters.AddService(typeof(ApiResultFilter));
                    config.Filters.AddService(typeof(ErrorFilter));
                })
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

 

注意:

打上的標簽無法獲取IOC容器

不要使用全局配置與標簽一起使用 會造成多次調用

 

在這里推薦使用過濾器而不是中間件,

 

貼上一張大佬的過濾器調用圖

 

 

結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM