列表单文件上传异常:空记录导致ASP.NET Core控制器报错求助
列表上传空记录报错问题解决
问题描述
实现了ASP.NET Core的列表上传功能,支持为每条记录上传文件并统一提交到控制器,正常上传时有文件的记录可以正常运行,但当某条记录未上传文件(即文件字段为空)时会触发错误。控制器代码如下:
[HttpPost] public async Task<IActionResult> SabtEditTaxParvanedAsync([FromForm]IEnumerable<TaxParvande> taxParvandes) { if (taxParvandes == null) { return Content("File not selected"); } foreach (var item in taxParvandes) { var path = Path.Combine(_environment.WebRootPath, "ListUpload", item.prosessMastand.FileName); using (FileStream stream = new FileStream(path, FileMode.Create)) { await item.prosessMastand.CopyToAsync(stream); stream.Close(); } var taxDomainModel = new TaxDomainModel { prosessId =item.prosessId, prosessName = item.prosessName, state = item.state, FilePath = path, }; _context.Add(taxDomainModel); await _context.SaveChangesAsync(); } return View(); }
错误原因
当某条记录未上传文件时,item.prosessMastand为null,此时访问item.prosessMastand.FileName会直接抛出空引用异常,后续的文件写入操作也会因为prosessMastand为null而失败。
解决方案
在遍历每条记录时,先检查文件字段是否为空,根据业务需求跳过无文件记录或单独处理这类记录,同时完善空值判断逻辑:
修改后的控制器代码
[HttpPost] public async Task<IActionResult> SabtEditTaxParvanedAsync([FromForm]IEnumerable<TaxParvande> taxParvandes) { if (taxParvandes == null || !taxParvandes.Any()) { return Content("没有可处理的记录"); } foreach (var item in taxParvandes) { // 校验文件是否有效:非空、有内容、有文件名 bool hasValidFile = item.prosessMastand != null && item.prosessMastand.Length > 0 && !string.IsNullOrEmpty(item.prosessMastand.FileName); if (!hasValidFile) { // 业务需求:保存无文件的记录,FilePath设为null或空字符串(根据数据库字段定义调整) var taxDomainModel = new TaxDomainModel { prosessId = item.prosessId, prosessName = item.prosessName, state = item.state, FilePath = null }; _context.Add(taxDomainModel); await _context.SaveChangesAsync(); continue; } // 处理有文件的记录:生成唯一文件名避免覆盖 var fileName = Path.GetFileName(item.prosessMastand.FileName); var uniqueFileName = $"{Guid.NewGuid()}_{fileName}"; var path = Path.Combine(_environment.WebRootPath, "ListUpload", uniqueFileName); using (var stream = new FileStream(path, FileMode.Create)) { await item.prosessMastand.CopyToAsync(stream); // using块会自动释放stream,无需手动Close() } var taxDomainModelWithFile = new TaxDomainModel { prosessId = item.prosessId, prosessName = item.prosessName, state = item.state, FilePath = path, }; _context.Add(taxDomainModelWithFile); await _context.SaveChangesAsync(); } return View(); }
关键优化点
- 添加
taxParvandes.Any()判断,避免空集合进入遍历逻辑 - 对每条记录的文件字段做三重校验,确保文件有效
- 支持两种业务场景:跳过无文件记录/保存无文件记录(代码中默认保存,可根据需求调整)
- 生成唯一文件名(Guid+原文件名),避免同名文件覆盖
- 移除手动的
stream.Close(),利用using块自动释放资源
内容的提问来源于stack exchange,提问作者sadegh
相关产品推荐
相关产品推荐

