WebAPI
本页是 AgileLabs Framework WebAPI 的主题总览页,聚合返回封包、异常处理、认证授权和 Swagger 对齐约定。正式规则请优先阅读 框架规范 / WebAPI 规范,需要看统一封包细节时直接进入 EnvelopMessage。
适用场景
ApiController控制器。- 使用
EnvelopMessage、异常过滤器和 API 异常处理器的项目。 - 需要接入 ASP.NET Core 认证授权的服务。
必须遵守
- 标准 API 响应必须保持统一封包;对前端暴露的默认协议固定为
{ data, code, msg, errMsg, tid }。 - 对统一 JSON API 而言,只要请求已经进入应用程序层并且仍可写回响应,HTTP 状态码固定为
200。 - API 过滤器同时配置
ExceptionHandlerFilter与EnvelopFilterAttribute,除非接口显式跳过封包。 - 模型验证与业务异常统一走异常处理链,不在每个 Action 手写重复
ModelState分支和catch(Exception)JSON 拼装。 - 认证授权接入必须统一,要么框架集成,要么宿主显式接入,不做半自动半手工混用。
/fwdev、/req_stat、/jobs等敏感入口必须受保护。- 业务可预期错误统一映射到规范化返回,不把数据库异常或系统异常堆栈直接返回给前端。
推荐做法
- 用
EnvelopFilterAttribute或项目级统一封包层承接成功返回包装,具体接法见 EnvelopMessage。 - 用
IApiExceptionProcessor和统一授权结果处理器承接项目级异常映射与 challenge/forbid 映射。 - 认证规则统一使用 ASP.NET Core 标准授权机制。
- Swagger 文档对齐真实响应封包,避免文档和实际返回不一致。
- 开放接口、回调接口和健康检查接口单独标明匿名访问策略。
源码入口
AgileLabs.WebApp/AspNet/WebApis/Filters/EnvelopFilterAttribute.cs:成功响应统一封包。AgileLabs.WebApp/AspNet/WebApis/Filters/ExceptionHandlerFilter.cs:模型校验和异常总入口。AgileLabs.WebApp/AspNet/WebApis/Filters/DefaultApiExceptionProcessor.cs:把异常映射成EnvelopMessage。AgileLabs.WebApp/AspNet/WebApis/Exceptions/ApiException.cs:业务错误基类。AgileLabs.WebApp/AspNet/WebApis/Exceptions/ModelValidateException.cs:模型验证错误。EnvelopMessage的字段语义、最小配置和扩展示例统一收口到 EnvelopMessage。
WebAPI 总体关注点
WebAPI 主题里最需要优先确认的是四件事:
- 返回包是不是统一的。
- 模型校验、业务异常和系统异常是不是都走统一异常链。
- 认证授权到底由框架集成还是宿主显式接入。
- 文档描述的是最终对前端暴露的协议,还是 Controller 的裸返回类型。
其中第一件和第二件的详细机制,统一收口在 EnvelopMessage。本页只保留 WebAPI 级别的总入口和跨主题约束。
异常映射总览
ExceptionHandlerFilter 会把校验失败和执行期异常统一交给 IApiExceptionProcessor。默认处理器的行为可以概括成这张表:
| 异常类型 | 处理器行为 | 对前端的结果 |
|---|---|---|
ModelValidateException |
不输出错误日志,提取字段错误 | HTTP 200 + code=400 |
ApiException |
不输出错误日志,保留业务码 | HTTP 200 + 业务错误 code |
DbException |
映射为数据库错误 | HTTP 200 + code=500 |
其他 Exception |
兜底处理 | HTTP 200 + code=500 |
最小处理器写法、返回链路图和 IgnoreEnvelopAttribute 用法见 EnvelopMessage。
认证授权接入位置
- 请求管道阶段里,框架会在
UseRouting()之后、UseEndpoints()之前插入认证授权。 - 如果
buildContext.FeatureSwitch.IsIntegrateAspNetAuthentication为真,框架会自动执行UseAuthentication()和UseAuthorization()。 - 如果项目不走框架集成,就必须在宿主自己的管道注册里完整接入,不要出现“控制器上写了
[Authorize],但管道里没跑授权中间件”的半接入状态。
Swagger 与封包对齐点
- Swagger 不是描述 Controller 里返回了什么对象,而是描述最终对前端暴露的协议。
- 如果宿主已启用统一封包,Swagger 文档也必须体现封包后的结构。
- 如果某些 Action 使用
IgnoreEnvelopAttribute,就应把它们标记成特例接口,而不是默认接口。
常见误接法对照
| 误接法 | 风险 | 正确做法 |
|---|---|---|
Controller 手工 return new JsonResult(...) 拼封包 |
不同接口字段漂移 | 由统一过滤器封包 |
Action 里 catch (Exception) 后直接返回 JSON |
绕开统一异常链 | 抛给 ExceptionHandlerFilter |
只注册 UseAuthentication() |
授权不生效 | 认证和授权一起挂 |
| Swagger 仍描述裸对象 | 前后端理解不一致 | 文档对齐真实封包 |
常见坑
- 有的接口返回裸对象,有的接口返回封包对象。
- 对前端有的接口返回
camelCase,有的接口返回PascalCase。 - 只注册
UseAuthentication()不注册UseAuthorization()。 - 把系统异常堆栈直接返回给前端。
- 在控制器里
catch (Exception)后手动拼 JSON,绕开统一异常处理链。
示例与落地对照
niusys-webapi:EnvelopMessage、Swagger 封包适配、JWT + ApiKey。gmandarin-backend:宿主层启用IsIntegrateAspNetAuthentication = true。woscm:项目级异常处理器、业务错误码、TraceId 回写。