如何在ASP.NET Core 5 Web API中创建统一通用API响应类
ASP.NET Core 5 Web API 统一通用API响应类实现方案
问题核心是原实现中Data属性强绑定为IEnumerable<T>类型,无法兼容字符串类型的错误信息,以下是两种可落地的实现方式:
方案一:分层属性设计(推荐,符合API设计规范)
不要将数据和错误信息硬塞到同一个字段,拆分独立属性承载不同内容,前端解析逻辑更清晰,不需要做额外类型判断。
第一步:定义通用响应类
加入静态辅助方法,减少每次手动构造响应对象的重复代码:
public class ApiResponse<T> { /// <summary> /// 响应状态码 /// </summary> public int StatusCode { get; set; } /// <summary> /// 返回结果数量,错误/无数据时为0 /// </summary> public int ResultCount { get; set; } /// <summary> /// 成功时返回的数据集合 /// </summary> public IEnumerable<T> Data { get; set; } /// <summary> /// 失败时返回的错误信息集合 /// </summary> public string[] Errors { get; set; } /// <summary> /// 构造成功响应 /// </summary> public static ApiResponse<T> Success(int statusCode, IEnumerable<T> data) { return new ApiResponse<T> { StatusCode = statusCode, ResultCount = data?.Count() ?? 0, Data = data ?? Enumerable.Empty<T>(), Errors = Array.Empty<string>() }; } /// <summary> /// 构造失败响应 /// </summary> public static ApiResponse<T> Error(int statusCode, params string[] errorMessages) { return new ApiResponse<T> { StatusCode = statusCode, ResultCount = 0, Data = Enumerable.Empty<T>(), Errors = errorMessages ?? Array.Empty<string>() }; } }
第二步:控制器中调用
[HttpGet] public IActionResult GetAll() { var userList = _userRepository.GetAll(); // 构造200成功响应 var successResp = ApiResponse<User>.Success(StatusCodes.Status200OK, userList); return Ok(successResp); } [HttpGet("{id}")] public IActionResult GetById(int id) { var targetUser = _userRepository.GetById(id); if (targetUser == null) { // 构造404错误响应 var notFoundResp = ApiResponse<User>.Error(StatusCodes.Status404NotFound, "未找到匹配的用户数据"); return NotFound(notFoundResp); } var successResp = ApiResponse<User>.Success(StatusCodes.Status200OK, new List<User> { targetUser }); return Ok(successResp); }
如果需要全局统一处理响应,还可以通过Action过滤器、中间件自动捕获接口返回结果/未处理异常,自动包装为该统一格式,不需要每个接口手动编写构造逻辑。
方案二:单字段兼容多类型(严格匹配初始结构设计,不推荐)
如果必须保持Response单字段同时承载数据和错误信息,可以将该字段类型改为object,兼容任意类型赋值:
public class Result<T> { public int StatusCode { get; set; } public int ResultCount { get; set; } public object Response { get; set; } }
使用时成功场景给Response赋值IEnumerable<T>类型的数据集合,错误场景赋值字符串/字符串数组类型的错误信息即可。但这种方式前端需要先根据StatusCode判断响应类型,再对Response做对应类型的反序列化,联调和维护成本更高。
内容的提问来源于stack exchange,提问作者Nilesh
相关产品推荐
相关产品推荐

