Files
ft/CodexOutput/upserver/服务端4xx写入可能性核查-2026-09-22.md

2.5 KiB
Raw Blame History

服务端4xx写入可能性核查(阶段3B审查证据)

日期:2026-09-22。核查人:主会话(ZCode),应用户2026-09-22裁决第4项执行。方式:只读源码核查,无服务端修改、无请求发送、无正式服操作。

核查对象

  • 服务端仓库 C:/projects/N3-Server-CN,HEAD 858fe7c(KV 功能提交 a3d3faa)。
  • 入口:LeaderboardAPI/Controllers/PlayerDataApi.cs([Authorize],路由 playerdata/Get|Set|Delete)。
  • 服务层:LeaderboardBLL/Services/PlayerKV/PlayerKVService.cs(EF Core → MySQL PlayerKV 表,SaveChangesAsync 单点提交)。
  • DTO:LeaderboardBLL/Models/PlayerKVModel.cs(Set.data / Delete.keys 带 [Required])。
  • 管道:LeaderboardAPI/Program.cs(Cookie 认证;OnRedirectToLogin/OnRedirectToAccessDenied 改写为 403;未发现把异常转成 4xx 的中间件)。

变更请求(Set/Delete)的 4xx 路径清单

状态码 产生点 相对写入时机
401/403 Cookie 认证/授权(未认证、会话过期、拒绝) 动作执行前,未写
400 [ApiController] 模型绑定/校验(JSON 不可解析、data/keys 缺失) 动作执行前,未写
400 ResolvePlayerId 失败(NameIdentifier 缺失/非十进制) SetAsync/DeleteAsync 调用前,未写

控制器在 SetAsync/DeleteAsync 返回后仅回 200;服务层自身不产生 4xx;数据库/EF 异常未被任何中间件改写状态码,按 ASP.NET Core 默认成为 500。

结论

当前服务端版本(858fe7c)下,playerdata 变更请求的 4xx(400/401/403)全部产生于服务端写入之前,不存在"已写入后返回 4xx"的代码路径;写入之后的失败表现为 5xx。

边界与不改变项

  1. 本结论为源码级、版本 858fe7c 时点结论;服务端后续更新需重新复核。
  2. 客户端本批不改动:非 200 仍一律保守按 MayHaveCommitted 处理(含 4xx)。若后续要以本证据将 4xx 降级为"确定未提交",须按差异裁决单独评审修改 PlayerKVClient 及相关测试,不并入 3B 实施范围。
  3. 500/超时/网络中断的 MayHaveCommitted 语义不受本核查影响(提交确认丢失等场景仍然可能)。
  4. Set 空字典 / Delete 空列表为 200 no-op;Set 批内多键经单次 SaveChangesAsync(EF 默认隐式事务)提交,不构成跨请求原子性。
  5. 若部署拓扑插入会改写状态码的反向代理,需在最终包环境复核;当前客户端直连 http://s101.local:18080/。