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

逗号分隔字符串转List报Collection was modified错误的代码排查

错误原因

  1. 直接报错诱因:你正在使用foreach遍历stringList集合的同时,调用Add方法修改了该集合的内容。C#的foreach遍历机制要求遍历期间集合不能发生增、删操作,否则就会抛出Collection was modified异常。
  2. 隐藏逻辑缺陷:就算绕过了遍历报错,你的stringList最终会同时包含拆分得到的短文件名(比如Image01.jpg)和拼接后的全路径,后续for循环读取文件时,遇到短文件名会直接报文件不存在错误,完全达不到预期效果。

修复方案

不需要在遍历的时候往原集合新增元素,直接拆分完文件名列表后,逐元素做路径拼接处理即可,推荐两种修改方式:

方式1:合并遍历逻辑,直接处理路径

把原来的foreach拼接路径、for循环压缩文件的逻辑合并,不需要修改原始文件名集合:

public FileResult DownloadZipFile(string StudentList)
{
    var fileName = $"{DateTime.Today:dd-MM-yyyy}_1_ImageFiles.zip";
    var tempOutPutPath = Path.Combine(Server.MapPath("~/Assets/Student_ID"), fileName);

    using (ZipOutputStream s = new ZipOutputStream(System.IO.File.Create(tempOutPutPath)))
    {
        s.SetLevel(9); 
        byte[] buffer = new byte[4096];
        // 拆分得到文件名列表,过滤空值避免异常
        List<string> fileNames = StudentList.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();

        foreach (string fileName in fileNames)
        {
            // 直接拼接全路径,不需要存入原集合
            string fullPath = Server.MapPath($"~/Assets/Student_ID/{fileName}");
            // 可选:跳过不存在的文件,避免单个文件异常导致整个接口报错
            if(!System.IO.File.Exists(fullPath)) continue;

            ZipEntry entry = new ZipEntry(Path.GetFileName(fullPath));
            entry.DateTime = DateTime.Now;
            entry.IsUnicodeText = true;
            s.PutNextEntry(entry);

            using (FileStream fs = System.IO.File.OpenRead(fullPath))
            {
                int sourceBytes;
                do
                {
                    sourceBytes = fs.Read(buffer, 0, buffer.Length);
                    s.Write(buffer, 0, sourceBytes);
                } while (sourceBytes > 0);
            }
        }

        s.Finish();
        s.Flush();
        s.Close();
    }

    byte[] finalResult = System.IO.File.ReadAllBytes(tempOutPutPath);
    if (System.IO.File.Exists(tempOutPutPath))
        System.IO.File.Delete(tempOutPutPath);

    if (finalResult == null || finalResult.Length == 0)
        throw new Exception("未找到匹配的图片文件");

    return File(finalResult, "application/zip", fileName);
}

方式2:新建集合存储全路径

如果你需要单独维护全路径集合,就新开一个List存储,不要修改正在遍历的原始集合:

// 拆分得到原文件名列表
List<string> fileNames = StudentList.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
// 新开集合存储全路径,不修改遍历中的原集合
List<string> fullPaths = new List<string>();
foreach(string fileName in fileNames)
{
    fullPaths.Add(Server.MapPath($"~/Assets/Student_ID/{fileName}"));
}
// 后续遍历fullPaths处理压缩逻辑即可

额外优化建议

  • 路径拼接推荐使用Path.Combine,避免手动拼接出现斜杠多写、漏写的问题
  • Split时增加StringSplitOptions.RemoveEmptyEntries参数可以过滤空值,避免传入的字符串首尾带逗号时生成无效空文件名
  • 可增加文件存在性判断,避免单个文件缺失导致整个下载接口报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 11:54:03