ASP.NET Core 3.1 仓储模式更新轮播时未换图仍误删原图片的优化方案
问题根因
原有服务层的更新逻辑存在硬伤:不判断新旧图片是否一致,一进入方法就无条件删除磁盘上的原有轮播图文件。哪怕控制器层在没收到新上传图片时,已经把原图片路径原样回传给服务层,服务层还是会先把旧文件删掉,自然就出现“不换图也丢文件”的异常。
优化后的服务层实现
核心调整:仅当传入的新图片文件名和数据库存储的旧文件名不同时,才触发旧文件删除操作;文件名一致时直接跳过删除流程,只更新其他字段。
public async Task UpdateSlider(int id, bool isPashto, string img, string desc, bool notshow, int order, string intro) { Slider slider = await _context.Sliders.FindAsync(id); // 仅新旧图片名不一致时,才删除原磁盘文件 if (!string.Equals(slider.Img, img, StringComparison.OrdinalIgnoreCase)) { var filepath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/images/sliders/", slider.Img); if (System.IO.File.Exists(filepath)) { System.IO.File.Delete(filepath); } } slider.Img = img; slider.IsPastho = isPashto; slider.Desc = desc; slider.NotShow = notshow; slider.OrderShow = order; slider.Intro = intro; await _context.SaveChangesAsync(); }
优化后的控制器层实现
原有控制器层的核心判断逻辑基本合理,仅需补两个边界细节,避免潜在异常:
- 上传判断增加文件大小校验,避免空文件触发无效上传
- 新文件名直接基于上传的文件流生成,不要在编辑页回显的旧文件名上直接拼接,防止文件名重复拼接的问题
[HttpPost] public async Task<IActionResult> EditSlider(AdminSliderViewModel viewModel, int id) { if (ModelState.IsValid) { Slider slider = await _admin.GetSlider(id); // 默认沿用数据库存储的原有图片名 string sliderImg = slider.Img; // 仅当用户确实上传了有效新图片时,才执行上传、更新图片名 if (viewModel.Img != null && viewModel.Img.Length > 0) { // 直接基于上传文件生成唯一新文件名,避免在旧回显值上拼接 string newImgName = $"{Guid.NewGuid()}-{viewModel.Img.FileName}"; string filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/images/sliders/", newImgName); using (var stream = new FileStream(filePath, FileMode.Create)) { await viewModel.Img.CopyToAsync(stream); } sliderImg = newImgName; } await _admin.UpdateSlider(id, viewModel.IsPashto, sliderImg, viewModel.Desc, viewModel.NotShow, viewModel.OrderShow, viewModel.Intro); return RedirectToAction(nameof(ShowSliders)); } return View(viewModel); }
注意点:
- 调整后,不更换图片时控制器会把原数据库存储的图片名直接传给服务层,服务层判断新旧名一致后直接跳过删除步骤,不会误删原有文件
- 更换图片时,控制器会生成新的唯一文件名保存到磁盘,服务层判断新旧名不一致后,才会删除磁盘上的旧文件
- 相比原代码,增加了异步文件写入的
CopyToAsync调用,避免文件大时阻塞请求线程
内容的提问来源于stack exchange,提问作者Muhammad_Shirzad
相关产品推荐
相关产品推荐

