ASP.NET Core中设置IFormFile文件名的最佳方法是什么?
问题本质
IFormFile是ASP.NET Core封装HTTP上传文件的原生类型,其FileName属性仅代表客户端上传的原始文件名,设计上为只读,不需要也不应该修改。你遇到的问题核心是把「接收上传的临时属性」和「要持久化存储的业务属性」混为一谈了。
最佳实现方案
1. 调整模型设计
区分上传用临时属性和存库用业务属性,不要直接把IFormFile类型的属性映射到数据库:
public class LendOutEquipmentViewModel { // 其他原有业务属性... [NotMapped] // 告知EF Core该属性无需映射到数据库字段 public List<IFormFile> Picture { get; set; } // 新增属性:专门存储处理后的唯一文件名,会被持久化到数据库 public List<string> PictureUniqueNames { get; set; } = new(); }
如果你的数据库实体类和ViewModel是拆分的,只需要在实体类中加存储文件名的属性即可,不需要给ViewModel加[NotMapped]注解。
2. 修改上传处理逻辑
生成唯一文件名后直接赋值给专门的存库属性,不需要修改IFormFile本身的属性:
[HttpPost] public async Task<IActionResult> Index(LendOutEquipmentViewModel model) { if (ModelState.IsValid && model.Picture!=null) { long size = model.Picture.Sum(f => f.Length); var uploadFolderPath = Path.Combine(_hostingEnvironment.WebRootPath, "Upload"); // 提前判断上传目录是否存在,避免创建文件报错 if (!Directory.Exists(uploadFolderPath)) { Directory.CreateDirectory(uploadFolderPath); } foreach (var picture in model.Picture) { if (picture.Length > 0) { var uniqueFileName = GetUniqueFileName(picture.FileName); var filePath = Path.Combine(uploadFolderPath,uniqueFileName); using (var stream = System.IO.File.Create(filePath)) { await picture.CopyToAsync(stream); } // 把生成的唯一文件名存入要持久化的属性 model.PictureUniqueNames.Add(uniqueFileName); } } DbContext.Equipments.Add(model); DbContext.SaveChanges(); return Redirect("/BorrowEquipment"); } return View(model); }
3. 后续读取规则
后续需要访问上传的文件时,直接用PictureUniqueNames中存储的文件名拼接上传目录路径即可,不需要再调用原始IFormFile的FileName属性。
内容的提问来源于stack exchange,提问作者Nichlas Birkholm
相关产品推荐
相关产品推荐

