.Net Core Mvc/WebApi 返回结果封装

一.背景

为了方便开发,简化代码,也为了与前端方便对接,需要对接口服务返回结果进行统一处理.

.Net Core 中返回结果的处理与 .Net Framework 中的处理不一样.

.Net Core 返回结果处理继承自 ActionFilterAttribute , OnActionExecuted 的参数为 ActionExecutedContext.

我们需要对之前的处理进行修改.

二.封装

1.首先定义一个统一返回结果类

我们需要定义一个统一返回结果类ReturnObject简写为Robj

约定返回结果Code

 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     }
View Code

返回结果对象类

 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     }
View Code

2.添加返回结果处理Filter

说一下NoPackageResultAttribute特性

/// <summary>
/// 标识不对返回的结果进行封装处理
/// </summary>
public class NoPackageResultAttribute : Attribute
{
}

之前 .net Framework WebApi时,需要添加一个NoPackageResultAttribute,以处理接口不需要进行统一封装时使用.比如下载文件接口.

现在 .net Core 中已经不需要了.

下面开始添加对返回结果进行处理的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     }
View Code

重点说明下:

(1)此处只处理Exception为Null即非异常情况.异常结果处理在另一个ExceptionHandlingMiddleware中做统一处理.

(2)只处理actionExecutedContext.Result为ObjectResult且不为Null的情况.

    这样就不会对返回的其它ActionResult进行处理.比如FileResult,ContentResult,JsonResult等.

    如果不需要封装的时候,只要接口返回你想要的IActionResult即可.

 所以上面第一步的NoPackageResultAttribute特性在.net Core中可以不使用了.

3.完整代码如下

  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     }
View Code

4.使用Filter

在StartUp ConfigureServices方法中引入Filter

services.AddMvc(options =>
{   //加入返回结果处理
    options.Filters.Add<ApiResultFilter>();
})

 5.返回结果

查看返回结果如下:

{"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":"操作成功"}

原文地址:https://www.cnblogs.com/arthur3k/p/11169153.html