爲了方便開發,簡化代碼,也爲了與前端方便對接,須要對接口服務返回結果進行統一處理.前端
.Net Core 中返回結果的處理與 .Net Framework 中的處理不同.ide
.Net Core 返回結果處理繼承自 ActionFilterAttribute , OnActionExecuted 的參數爲 ActionExecutedContext.測試
咱們須要對以前的處理進行修改.this
咱們須要定義一個統一返回結果類ReturnObject簡寫爲Robjspa
約定返回結果Code.net
1 /// <summary> 2 /// 返回Code 3 /// </summary> 4 public enum RCode 5 { 6 /// <summary> 7 /// 成功 8 /// </summary> 9 [JsonProperty("1000")] 10 Success = 1000, 11 12 /// <summary> 13 /// 登陸超時,需從新登陸 14 /// </summary> 15 [JsonProperty("2000")] 16 NeedLogin = 2000, 17 18 /// <summary> 19 /// 程序異常 20 /// </summary> 21 [JsonProperty("3000")] 22 Exception = 3000, 23 24 /// <summary> 25 /// 系統錯誤 26 /// </summary> 27 [JsonProperty("4000")] 28 SysError = 4000 29 }
返回結果對象類3d
1 /// <summary> 2 /// 返回結果對象 3 /// ReturnObject Robj 4 /// 默認RCode爲成功,Message爲成功. 5 /// </summary> 6 /// <typeparam name="T"></typeparam> 7 public class Robj<T> 8 { 9 T result = default(T); 10 RCode code = RCode.Success; 11 string message = "操做成功"; 12 13 /// <summary> 14 /// 結果 15 /// </summary> 16 public T Result 17 { 18 get { return result; } 19 set { result = value; } 20 } 21 /// <summary> 22 /// 執行結果 23 /// </summary> 24 public RCode Code 25 { 26 get { return code; } 27 set { code = value; } 28 } 29 /// <summary> 30 /// 提示消息 31 /// </summary> 32 public string Message 33 { get { return message; } set { message = value; } } 34 35 /// <summary> 36 /// 成功 37 /// </summary> 38 /// <param name="result">返回結果</param> 39 /// <param name="msg">提示消息</param> 40 public void Success(T result,string msg = "操做成功") 41 { 42 this.code = RCode.Success; 43 this.result = result; 44 this.Message = msg; 45 } 46 47 /// <summary> 48 /// 異常 49 /// </summary> 50 /// <param name="msg">提示消息</param> 51 /// <param name="code"></param> 52 public void Error(string msg,RCode code = RCode.Exception) 53 { 54 this.code = code; 55 this.Message = msg; 56 } 57 }
說一下NoPackageResultAttribute特性code
/// <summary> /// 標識不對返回的結果進行封裝處理 /// </summary> public class NoPackageResultAttribute : Attribute { }
以前 .net Framework WebApi時,須要添加一個NoPackageResultAttribute,以處理接口不須要進行統一封裝時使用.好比下載文件接口.對象
如今 .net Core 中已經不須要了.blog
下面開始添加對返回結果進行處理的Filter,Filter繼承自ActionFilterAttribute,重寫OnActionExecuted方法.
1 /// <summary> 2 /// ApiResult封裝 3 /// </summary> 4 public class ApiResultFilter : ActionFilterAttribute 5 { 6 /// <summary> 7 /// Action執行完成,返回結果處理 8 /// </summary> 9 /// <param name="actionExecutedContext"></param> 10 public override void OnActionExecuted(ActionExecutedContext actionExecutedContext) 11 { 12 if (actionExecutedContext.Exception == null) 13 { //執行成功 取得由 API 返回的資料 14 ObjectResult result = actionExecutedContext.Result as ObjectResult; 15 if (result != null) 16 { // 從新封裝回傳格式 17 Robj<object> robj = new Robj<object>(); 18 robj.Success(result.Value); 19 ObjectResult objectResult = new ObjectResult(robj); 20 actionExecutedContext.Result = objectResult; 21 } 22 } 23 base.OnActionExecuted(actionExecutedContext); 24 } 25 }
重點說明下:
(1)此處只處理Exception爲Null即非異常狀況.異常結果處理在另外一個ExceptionHandlingMiddleware中作統一處理.
(2)只處理actionExecutedContext.Result爲ObjectResult且不爲Null的狀況.
這樣就不會對返回的其它ActionResult進行處理.好比FileResult,ContentResult,JsonResult等.
若是不須要封裝的時候,只要接口返回你想要的IActionResult便可.
因此上面第一步的NoPackageResultAttribute特性在.net Core中能夠不使用了.
1 /// <summary> 2 /// ApiResult封裝 3 /// </summary> 4 public class ApiResultFilter : ActionFilterAttribute 5 { 6 /// <summary> 7 /// Action執行完成,返回結果處理 8 /// </summary> 9 /// <param name="actionExecutedContext"></param> 10 public override void OnActionExecuted(ActionExecutedContext actionExecutedContext) 11 { 12 if (actionExecutedContext.Exception == null) 13 { //執行成功 取得由 API 返回的資料 14 ObjectResult result = actionExecutedContext.Result as ObjectResult; 15 if (result != null) 16 { // 從新封裝回傳格式 17 Robj<object> robj = new Robj<object>(); 18 robj.Success(result.Value); 19 ObjectResult objectResult = new ObjectResult(robj); 20 actionExecutedContext.Result = objectResult; 21 } 22 } 23 base.OnActionExecuted(actionExecutedContext); 24 } 25 } 26 27 /// <summary> 28 /// 返回結果對象 29 /// ReturnObject Robj 30 /// 默認RCode爲成功,Message爲成功. 31 /// </summary> 32 /// <typeparam name="T"></typeparam> 33 public class Robj<T> 34 { 35 T result = default(T); 36 RCode code = RCode.Success; 37 string message = "操做成功"; 38 39 /// <summary> 40 /// 結果 41 /// </summary> 42 public T Result 43 { 44 get { return result; } 45 set { result = value; } 46 } 47 /// <summary> 48 /// 執行結果 49 /// </summary> 50 public RCode Code 51 { 52 get { return code; } 53 set { code = value; } 54 } 55 /// <summary> 56 /// 提示消息 57 /// </summary> 58 public string Message 59 { get { return message; } set { message = value; } } 60 61 /// <summary> 62 /// 成功 63 /// </summary> 64 /// <param name="result">返回結果</param> 65 /// <param name="msg">提示消息</param> 66 public void Success(T result,string msg = "操做成功") 67 { 68 this.code = RCode.Success; 69 this.result = result; 70 this.Message = msg; 71 } 72 73 /// <summary> 74 /// 異常 75 /// </summary> 76 /// <param name="msg">提示消息</param> 77 /// <param name="code"></param> 78 public void Error(string msg,RCode code = RCode.Exception) 79 { 80 this.code = code; 81 this.Message = msg; 82 } 83 } 84 85 /// <summary> 86 /// 返回Code 87 /// </summary> 88 public enum RCode 89 { 90 /// <summary> 91 /// 成功 92 /// </summary> 93 [JsonProperty("1000")] 94 Success = 1000, 95 96 /// <summary> 97 /// 登陸超時,需從新登陸 98 /// </summary> 99 [JsonProperty("2000")] 100 NeedLogin = 2000, 101 102 /// <summary> 103 /// 程序異常 104 /// </summary> 105 [JsonProperty("3000")] 106 Exception = 3000, 107 108 /// <summary> 109 /// 系統錯誤 110 /// </summary> 111 [JsonProperty("4000")] 112 SysError = 4000 113 }
在StartUp ConfigureServices方法中引入Filter
services.AddMvc(options => { //加入返回結果處理 options.Filters.Add<ApiResultFilter>(); })
查看返回結果以下:
{"result":{"id":"9e8e9a12-1a9b-4856-b15f-cd8debc3fb44","userName":"test","nickName":"測試","roleType":2,"userStatus":1,"addUser":"909f2444-f625-4469-8bfb-353e999944ad","addDate":"2019-05-14 00:00:00","lastLoginToken":"e68f1765-7a7e-439b-aa55-c2491516d886","lastLoginTime":"2019-07-11 12:12:44","lastLoginIp":"127.0.0.1"},"code":1000,"message":"操做成功"}