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

ASP.NET Core 6.0 API GZip压缩响应解压时出现不支持压缩方法错误

问题根源

服务端的CompressString方法存在致命错误:将GZip压缩生成的二进制字节数组直接通过Encoding.UTF8.GetString(compressedData)转换为字符串。压缩后的字节流并非合法的UTF-8字符序列,这种转换会破坏原始二进制数据,导致客户端接收到的是损坏的压缩数据,解压时自然抛出不支持的压缩方法异常。

修复方案

方案一:直接返回二进制压缩数据(推荐)

这是HTTP传输压缩内容的标准做法,避免字符串转换带来的数据损坏。

修改服务端代码

[HttpPost("[action]", Name = "GetData")]
public IActionResult GetData(string request)
{
    string data = GetStaticXMLFileData();
    byte[] compressedData = CompressString(data);

    // 返回二进制压缩数据,指定正确的媒体类型与压缩标识
    Response.Headers.Add("Content-Encoding", "gzip");
    return File(compressedData, "text/xml");
}

private byte[] CompressString(string text)
{
    using (var memoryStream = new MemoryStream())
    {
        using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
        {
            using (var writer = new StreamWriter(gZipStream, Encoding.UTF8))
            {
                writer.Write(text);
            }
        }
        return memoryStream.ToArray();
    }
}

修改客户端代码

private string GetDataAPIResponse()
{
    string httpResponse = string.Empty;

    var urlValue = "https://localhost:44314/api/CompressedData/GetData?compress=true&result_format=xml";
    var requestUri = new Uri(urlValue);

    var buffer = Encoding.UTF8.GetBytes("<data>Test</data>");
    var byteContent = new ByteArrayContent(buffer);

    using (var httpClient = new HttpClient())
    {
        // 告知服务端客户端支持gzip压缩
        httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
        
        using (var response = httpClient.PostAsync(requestUri, byteContent).GetAwaiter().GetResult())
        {
            response.EnsureSuccessStatusCode();

            using (var responseStream = response.Content.ReadAsStreamAsync().GetAwaiter().GetResult())
            {
                Stream decompressStream = response.Content.Headers.ContentEncoding.Contains("gzip") 
                    ? new GZipStream(responseStream, CompressionMode.Decompress) 
                    : responseStream;

                using (var readStream = new StreamReader(decompressStream, Encoding.UTF8))
                {
                    httpResponse = readStream.ReadToEnd();
                }
            }
        }

        return httpResponse;
    }
}

方案二:Base64编码传输(仅当必须用字符串传输时)

如果业务限制必须返回字符串格式,可通过Base64编码确保二进制压缩数据安全传输,代价是传输体积增加约33%。

修改服务端代码

[HttpPost("[action]", Name = "GetData")]
public IActionResult GetData(string request)
{
    string data = GetStaticXMLFileData();
    string compressedBase64 = CompressStringToBase64(data);

    return new ContentResult
    {
        Content = compressedBase64,
        ContentType = "text/plain",
        StatusCode = (int)HttpStatusCode.OK
    };
}

private string CompressStringToBase64(string text)
{
    using (var memoryStream = new MemoryStream())
    {
        using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
        {
            using (var writer = new StreamWriter(gZipStream, Encoding.UTF8))
            {
                writer.Write(text);
            }
        }
        byte[] compressedData = memoryStream.ToArray();
        return Convert.ToBase64String(compressedData);
    }
}

修改客户端代码

private string GetDataAPIResponse()
{
    string httpResponse = string.Empty;

    var urlValue = "https://localhost:44314/api/CompressedData/GetData?compress=true&result_format=xml";
    var requestUri = new Uri(urlValue);

    var buffer = Encoding.UTF8.GetBytes("<data>Test</data>");
    var byteContent = new ByteArrayContent(buffer);

    using (var httpClient = new HttpClient())
    {
        using (var response = httpClient.PostAsync(requestUri, byteContent).GetAwaiter().GetResult())
        {
            response.EnsureSuccessStatusCode();

            string base64Content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
            byte[] compressedData = Convert.FromBase64String(base64Content);

            using (var memoryStream = new MemoryStream(compressedData))
            using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
            using (var readStream = new StreamReader(gZipStream, Encoding.UTF8))
            {
                httpResponse = readStream.ReadToEnd();
            }
        }

        return httpResponse;
    }
}

内容的提问来源于stack exchange,提问作者Creative Learner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 21:04:58