最近搭项目框架,为了便于接口返回值统一规范,做了一些配置,使得无论接口方法返回值是什么类型,都统一做了拦截,具体实现方式为:
首先需要几个过滤类:异常处理返回类,正常调用统一返回类,忽略返回格式类,
对应类代码如下:
异常处理返回类
using System;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
namespace S2_Xxxx_XxxNetApi
{
/// <summary>
/// Api action统一处理过滤器
/// 处理正常返回值
/// </summary>
public class ApiResultFilterAttribute : Attribute, IActionFilter
{
/// <summary>
/// 执行方法体之后
/// 返回结果为JsonResult的请求进行Result包装
/// </summary>
/// <param name="context"></param>
public void OnActionExecuted(ActionExecutedContext context)
{
//特殊处理:对有ApiIgnoreAttribute标签的,不进行返回结果包装,原样输出
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
if (controllerActionDescriptor != null)
{
var isDefined = controllerActionDescriptor.EndpointMetadata.Any(a => a.GetType().Equals(typeof(ApiIgnoreAttribute)));
if (isDefined)
{
return;
}
}
// 返回结果为JsonResult的请求进行Result包装
if (context.Result != null)
{
if (context.Result is ObjectResult)
{
var result = context.Result as ObjectResult;
context.Result = new JsonResult(new { code = 200, msg = "success", data = result.Value });
}
else if (context.Result is EmptyResult)
{
context.Result = new JsonResult(new { code = 200, msg = "success", data = new { } });
}
else if (context.Result is ContentResult)
{
var result = context.Result as ContentResult;
context.Result = new JsonResult(new { code = result.StatusCode, msg = result.Content });
}
else
{
throw new Exception($"未经处理的Result类型:{ context.Result.GetType().Name}");
}
}
}
/// <summary>
/// 执行方法体之前
/// </summary>
/// <param name="context"></param>
public void OnActionExecuting(ActionExecutingContext context)
{
//不做修改
}
}
}
正常调用统一返回类
using System;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
namespace S2_Xxxx_XxxNetApi
{
/// <summary>
/// Api action统一处理过滤器
/// 处理正常返回值
/// </summary>
public class ApiResultFilterAttribute : Attribute, IActionFilter
{
/// <summary>
/// 执行方法体之后
/// 返回结果为JsonResult的请求进行Result包装
/// </summary>
/// <param name="context"></param>
public void OnActionExecuted(ActionExecutedContext context)
{
//特殊处理:对有ApiIgnoreAttribute标签的,不进行返回结果包装,原样输出
var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
if (controllerActionDescriptor != null)
{
var isDefined = controllerActionDescriptor.EndpointMetadata.Any(a => a.GetType().Equals(typeof(ApiIgnoreAttribute)));
if (isDefined)
{
return;
}
}
// 返回结果为JsonResult的请求进行Result包装
if (context.Result != null)
{
if (context.Result is ObjectResult)
{
var result = context.Result as ObjectResult;
context.Result = new JsonResult(new { code = 200, msg = "success", data = result.Value });
}
else if (context.Result is EmptyResult)
{
context.Result = new JsonResult(new { code = 200, msg = "success", data = new { } });
}
else if (context.Result is ContentResult)
{
var result = context.Result as ContentResult;
context.Result = new JsonResult(new { code = result.StatusCode, msg = result.Content });
}
else
{
throw new Exception($"未经处理的Result类型:{ context.Result.GetType().Name}");
}
}
}
/// <summary>
/// 执行方法体之前
/// </summary>
/// <param name="context"></param>
public void OnActionExecuting(ActionExecutingContext context)
{
//不做修改
}
}
}
忽略返回格式类(这个类根据实际需求调整不需要拦截返回的类型)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace S2_Xxxx_XxxNetApi
{
/// <summary>
/// 使用该标签,对结果原样输出,不做包装
/// </summary>
public class ApiIgnoreAttribute : Attribute
{
}
}
然后在程序启动类注入相关方法
public void ConfigureServices(IServiceCollection services)
{
//注册过滤器
services.AddSingleton<ApiResultFilterAttribute>();
services.AddSingleton<ApiExceptionFilterAttribute>();
services.AddMvc(
config =>
{
config.EnableEndpointRouting = false;
config.Filters.AddService(typeof(ApiResultFilterAttribute));
config.Filters.AddService(typeof(ApiExceptionFilterAttribute));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
.AddNewtonsoftJson();
}
做对应测试就可返回对应的类型
这种返回值就比较统一规范,提高了前后端的协作;