2020/02/01, ASP.NET Core 3.1, VS2019html
摘要:基於ASP.NET Core 3.1 WebApi搭建後端多層網站架構【11-WebApi統一處理返回值、異常】
使用IExceptionFilter過濾器實現異常統一處理,使用IResultFilter過濾器實現統一處理返回值git
文章目錄github
此分支項目代碼後端
本章節介紹了使用IExceptionFilter實現異常統一處理,使用IResultFilter實現統一處理返回值api
在MS.WebApi
應用程序中新建Filters文件夾,在該文件夾下新建ApiExceptionFilter.cs
類:服務器
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Logging; using MS.Component.Aop; namespace MS.WebApi.Filters { /// <summary> /// api異常過濾器 /// </summary> public class ApiExceptionFilter : IExceptionFilter { private readonly ILogger<ApiExceptionFilter> _logger; public ApiExceptionFilter(ILogger<ApiExceptionFilter> logger) { _logger = logger; } public void OnException(ExceptionContext context) { string methodInfo = $"{context.RouteData.Values["controller"] as string}Controller.{context.RouteData.Values["action"] as string}:{context.HttpContext.Request.Method}"; //若是不是AopHandledException異常,則可能沒有記錄過日誌,進行日誌記錄 if (!(context.Exception is AopHandledException)) { _logger.LogError(context.Exception, "執行{0}時發生錯誤!", methodInfo); } context.Result = new JsonResult(new { status = 501, data = "服務器出錯" }); } } }
若是controller在執行過程當中遇到錯誤,則會被過濾器捕獲到,若是錯誤已經被LogAop(以前寫的業務層的)處理過,那在ApiExceptionFilter中判斷下就不處理了,最後統一返回501,提示服務器出錯架構
在Filters文件夾下新建ApiResultFilter.cs
類:mvc
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using System; namespace MS.WebApi.Filters { /// <summary> /// 給api返回結果包一層狀態碼 /// </summary> public class ApiResultFilter : IResultFilter { public void OnResultExecuting(ResultExecutingContext context) { if (context.Result != null) { if (context.Result is ObjectResult objectResult) { if (objectResult.DeclaredType is null) //返回的是IActionResult類型 { context.Result = new JsonResult(new { status = objectResult.StatusCode, data = objectResult.Value }); } else//返回的是string、List這種其餘類型,此時沒有statusCode,應儘可能使用IActionResult類型 { context.Result = new JsonResult(new { status = 200, data = objectResult.Value }); } } else if (context.Result is EmptyResult) { context.Result = new JsonResult(new { status = 200, data = "" }); } else { throw new Exception($"未經處理的Result類型:{ context.Result.GetType().Name}"); } } } public void OnResultExecuted(ResultExecutedContext context) { } } }
Startup.cs
類中,給AddControllers方法添加參數:網站
services.AddControllers(options => { options.Filters.Add<ApiResultFilter>(); options.Filters.Add<ApiExceptionFilter>(); });
將services.AddControllers();
改爲以上內容:
spa
至此,過濾器已應用成功,啓動項目,打開Postman調用接口:
能夠看到返回值已經包了一層
項目完成後,以下圖所示