You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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");
}

辅助验证步骤

  1. 用Postman/Curl直接调用源端接口,检查响应头的Content-Type字段:如果值为application/json则确认是序列化问题,修复后应为application/octet-stream
  2. 确认客户端使用标准的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 06:15:01