You need to enable JavaScript to run this app. ASP.NET Core 3.1 仓储模式更新轮播时未换图仍误删原图片的优化方案
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.03 01:36:06