.NET 5.0 微服务间收发字节数组长度不一致问题求助
问题根因与解决方案
核心原因:ASP.NET Core 默认序列化策略导致byte[]被Base64编码
你遇到的长度不匹配问题90%以上是由ASP.NET Core默认的JSON序列化行为导致的:
- 当Controller的Action直接返回
byte[]类型时,系统内置的System.Text.Json序列化器会自动将字节数组编码为Base64字符串再返回 - Base64编码的膨胀率固定为4/3,原始56129字节编码后大小约为
56129 * 4 / 3 ≈ 74838,和你观测到的74000左右的长度完全吻合
其他可能的次要原因
- 服务端存在全局响应包装中间件:部分项目会配置统一返回格式的中间件,将所有响应包裹为
{code:xxx, data:xxx, msg:xxx}的JSON结构,额外增加了内容长度 - 客户端读取方法异常:你代码中使用的
ReadAsByteAsync不是.NET HttpClient的标准方法,标准方法为ReadAsByteArrayAsync,如果是自定义扩展方法可能存在逻辑错误 - 反向代理/网关篡改响应:如果服务端和客户端之间有API网关、Nginx等反向代理,可能存在修改响应内容的配置
修复方案
优先修复服务端返回逻辑
将Action的返回值从byte[]改为IActionResult,直接返回二进制文件流,避免JSON序列化:
[HttpGet] [Route("resource")] public async Task<IActionResult> LocateResource(Guid Id) { if (Id== Guid.Empty) { throw new Exception("Invalid Id"); } var (content, message) = await _repo.LocateResource(Id); if (!message.Equals("Success")) { throw new Exception(message); } // 返回二进制流,指定MIME类型,禁止序列化 return File(content, "application/octet-stream"); }
辅助验证步骤
- 用Postman/Curl直接调用源端接口,检查响应头的
Content-Type字段:如果值为application/json则确认是序列化问题,修复后应为application/octet-stream - 确认客户端使用标准的
ReadAsByteArrayAsync方法读取响应:
public async Task<byte[]> ReadFile(Guid Id) { var response = await _httpClient.GetAsync($"{_urlOptions.Value.ReadFileEndpoint}?Id={Id}"); response.EnsureSuccessStatusCode(); // 替换为标准方法 var file = await response.Content.ReadAsByteArrayAsync(); return file; }
内容的提问来源于stack exchange,提问作者David Castro
相关产品推荐
相关产品推荐

