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

.Net5 API网关中间件无法正确读取Response.Body内容问题咨询

问题原因
  • 核心诱因:你的请求头携带Accept-Encoding: gzip标识,下游服务返回的响应体为gzip压缩后的二进制数据,直接读取压缩流转换为字符串会出现乱码。
  • 其他可能:若响应采用非UTF-8编码,StreamReader默认使用UTF-8解码也会出现乱码,你的场景优先排查压缩问题。
解决方案

方案1:移除压缩请求头(推荐,性能损耗最小)

在中间件调用后续管道前,移除请求的Accept-Encoding头,让下游服务返回未压缩的明文响应:

// 放在 await _next.Invoke(context); 之前执行
context.Request.Headers.Remove("Accept-Encoding");

如果需要给客户端返回压缩响应,可在网关的日志中间件之后,单独注册全局压缩中间件即可,不影响日志读取。

方案2:保留压缩逻辑,读取后解压

若必须透传压缩请求头给下游,需在读取响应时先根据Content-Encoding头判断压缩格式,解压后再转字符串:

using System.IO.Compression;
using System.Text;

// ... 其他原有逻辑
string responseBody = string.Empty;
var originalBodyStream = context.Response.Body;

using (var responseStream = new MemoryStream())
{
    context.Response.Body = responseStream;
    await _next.Invoke(context);
    context.Response.Body.Seek(0, SeekOrigin.Begin);

    if (context.Response.Headers.TryGetValue("Content-Encoding", out var encodingVal) 
        && encodingVal.Contains("gzip"))
    {
        // 处理gzip压缩响应
        using var decompressStream = new GZipStream(context.Response.Body, CompressionMode.Decompress);
        using var reader = new StreamReader(decompressStream, Encoding.UTF8);
        responseBody = await reader.ReadToEndAsync();
    }
    else
    {
        // 未压缩响应直接读取
        using var reader = new StreamReader(context.Response.Body, Encoding.UTF8);
        responseBody = await reader.ReadToEndAsync();
    }

    context.Response.Body.Seek(0, SeekOrigin.Begin);
    await responseStream.CopyToAsync(originalBodyStream);
}

若存在br等其他压缩格式,对应增加BrotliStream解压逻辑即可,处理逻辑与gzip一致。

内容的提问来源于stack exchange,提问作者Aristopher S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:36:04