.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()); } }
验证步骤
- 前端压缩后,打印
encodedCompressedJsonData的内容,确认无乱码; - 后端解码Base64后,对比字节数组长度是否与前端压缩后的长度一致;
- 解压后先输出字符串内容,确认是有效JSON再执行反序列化。
内容的提问来源于stack exchange,提问作者Anis Fatin Nabila Binti Ardhi
相关产品推荐
相关产品推荐

