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

C#使用Ionic.Zip打包下载重复触发时报相同键已添加错误如何解决?

问题原因
  • 你使用的DotNetZip库的ZipFile.AddFile()方法会以「压缩包内目标路径+文件名」作为唯一Key存入内部字典,同一个Key不允许重复添加。触发错误的核心原因是同一个Zip实例被多次添加了目标路径完全相同的文件,结合你的复现条件,常见诱因有2种:
    1. 你的数据源dt被多请求共享:如果dt被声明为静态变量、或者存储在Session/全局缓存中被复用,多次点击触发的并发请求会往同一个dt中追加重复的文件记录,导致单次请求循环时同一个文件路径被重复添加到新创建的Zip实例中。
    2. 同批文件本身存在重名:如果选中的多个源文件文件名完全相同,且都被添加到压缩包的files目录下,也会触发Key重复,不过该场景首次下载就会报错,不符合你的复现条件,可以优先排查上一种情况。
解决方案
  • 第一步:修复数据源复用问题
    禁止使用静态变量存储单次请求的查询结果dt,每次接收下载请求时都重新查询生成独立的dt实例,避免多请求数据互相污染。
  • 第二步:添加文件前做重复校验
    在调用AddFile前先判断压缩包内是否已存在相同路径的文件,避免重复添加,同时优化响应结束逻辑避免资源清理异常,代码修改如下:
    using (ZipFile zip = new ZipFile())
    {  
        foreach (DataRow row in dt.Rows)
        {
            // 此处保留你原来的业务逻辑代码
            string fileName = Path.GetFileName(filePath);
            string entryPath = Path.Combine("files", fileName);
            // 已存在则跳过,也可以根据需求重命名后添加(比如加(1)后缀)
            if (!zip.ContainsEntry(entryPath))
            {
                zip.AddFile(filePath, "files");
            }
        }
        Response.Clear();
        Response.AddHeader("Content-Disposition", "attachment; filename=DownloadedFile.zip"); 
        Response.ContentType = "application/zip";
        zip.Save(Response.OutputStream);
        // 替换Response.End()避免线程中止异常导致的资源清理异常
        Response.Flush();
        HttpContext.Current.ApplicationInstance.CompleteRequest();
    }
    
  • 第三步:前端防重复提交
    用户点击下载按钮后立即将按钮置为禁用状态,直到下载请求处理完成后再恢复,从入口避免短时间内多次重复请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 23:45:04