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

.Net控制器解压Gzip压缩JSON数据遇不支持压缩方法错误

.NET控制器解压前端Gzip压缩JSON时提示不支持的压缩方法的解决思路

报错信息

System.IO.InvalidDataException: 'The archive entry was compressed using an unsupported compression method.'


前端AJAX代码

function SaveQuestion(jsonData, formId, parentId, message, flatJsonData, isSaveAndCreate) {
    $('#overlay2').show();
    // Compress the JSON data using gzip
    var compressedJsonData = pako.gzip(jsonData, { to: 'string' });

    // Base64 encode the compressed data
    var encodedCompressedJsonData = btoa(compressedJsonData);

    $.ajax({
        url: "/IntelCollection/SaveDynamicForm",
        type: "POST",
        data: { formId: formId, jsonData: encodedCompressedJsonData, flatJsonData: flatJsonData, parentId: parentId },
        success: function (result) {
            if (isTest) {
                isTest = false;
                $('#tree').jstree(true).refresh();
                goForwardToCard3();
            }

            if (!isSaveAndCreate) {
                if (!isGoBack) {
                    refreshNodeId = result;
                }
                else {
                    isGoBack = false;
                }
            }
            else {
                refreshNodeId = 0;
            }

            $('#overlay2').hide();
            $("#tree").jstree(true).refresh();
            ReloadPreView();
            GrowlMessage(message, 'success');
        },
        error: function (request, status, error) {
            console.log(request.responseText);
        }
    });
}

.NET控制器代码

public async Task<string> SaveDynamicForm(int formId, string jsonData, string flatJsonData, string parentId = "", string optionId = "")
{
         // Call the Decompress method to get the decompressed JSON data
         string decompressedJson = Decompress(jsonData);

         var treeModel = JsonConvert.DeserializeObject<TreeModel>(decompressedJson);
}

现有解压函数代码

public static string Decompress(string value)
{
      byte[] compressedBytes = Convert.FromBase64String(value);
      string decompressedJson = "";

      using (MemoryStream compressedStream = new MemoryStream(compressedBytes))
      using (DeflateStream decompressionStream = new DeflateStream(compressedStream, CompressionMode.Decompress))
      using (MemoryStream decompressedStream = new MemoryStream())
      {
          // Decompress the data
          decompressionStream.CopyTo(decompressedStream);

          // Convert the decompressed bytes to a string
          decompressedJson = Encoding.UTF8.GetString(decompressedStream.ToArray());

      }
      return decompressedJson;
}

核心问题分析与解决方法

问题1:前端Base64编码逻辑错误

前端用pako.gzip(jsonData, { to: 'string' })得到的是UTF-8二进制字符串,直接用btoa()编码会丢失数据——btoa()仅支持ASCII字符,超出范围的字符会导致编码失真,后端解码后的字节数组损坏,最终触发解压错误。

修复前端代码:
将pako.gzip输出改为Uint8Array,再转换为Base64:

// 输出Uint8Array格式的压缩数据,而非字符串
var compressedJsonData = pako.gzip(jsonData);
// 将Uint8Array转换为合法的Base64字符串
var encodedCompressedJsonData = btoa(String.fromCharCode.apply(null, compressedJsonData));

问题2:后端解压流不匹配

前端用的是pako.gzip(标准Gzip格式),后端却用DeflateStream解压——Gzip是在Deflate基础上添加了文件头和校验信息的封装格式,直接用DeflateStream读取会识别为不支持的压缩方法。

修复后端解压函数:
替换为GZipStream:

public static string Decompress(string value)
{
    byte[] compressedBytes = Convert.FromBase64String(value);
    using (var compressedStream = new MemoryStream(compressedBytes))
    // 使用GZipStream匹配前端的Gzip压缩格式
    using (var decompressionStream = new GZipStream(compressedStream, CompressionMode.Decompress))
    using (var decompressedStream = new MemoryStream())
    {
        decompressionStream.CopyTo(decompressedStream);
        return Encoding.UTF8.GetString(decompressedStream.ToArray());
    }
}

验证步骤

  1. 前端压缩后,打印encodedCompressedJsonData的内容,确认无乱码;
  2. 后端解码Base64后,对比字节数组长度是否与前端压缩后的长度一致;
  3. 解压后先输出字符串内容,确认是有效JSON再执行反序列化。

内容的提问来源于stack exchange,提问作者Anis Fatin Nabila Binti Ardhi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 02:06:28