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

ASP.NET Core MVC多图上传问题:无法获取新建Gallery的Id

问题:ASP.NET Core MVC创建Gallery时无法关联上传多张图片

我使用ASP.NET Core MVC、C#和EF Core Code-First开发,目前遇到一个问题:创建Gallery时,无法将多张图片上传至指定文件夹并将对应路径存入数据库的GalleryImage表。多图上传的文件输入名为GalleryImages,对应的处理代码位于注释// Start multipleFile Upload Image Code.下方。

核心问题是创建Gallery时无法获取新生成的Gallery Id:用户提交表单时,需要将多张图片上传到包含Gallery Id的文件夹路径,并将路径存入GalleryImage表,但这一步必须依赖已生成的Gallery Id才能完成。只有在编辑已存在的Gallery时,多图上传功能才能正常工作,我尝试调整过多图上传代码的位置,但均未解决问题。


模型类

Gallery类

public class Gallery
{
    public Guid Id { get; set; }
    public string Title { get; set; }
    public bool IsPrivate { get; set; }
    public string? AccessCode { get; set; }
    public string ImageUrl { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime? UpdatedAt { get; set; }

    public int EventId { get; set; }
    public Event Event { get; set; }

    public int PhotographerId { get; set; }
    public Photographer Photographer { get; set; }

    [ValidateNever]
    public List<GalleryImage> GalleryImages { get; set; }
}

GalleryImage类

public class GalleryImage
{
    public int Id { get; set; }
    public string? ImageUrl { get; set; }

    public Guid GalleryId { get; set; }
    public Gallery Gallery { get; set; }
}

视图模型类(GalleryVM)

public Guid Id { get; set; }

[Required(ErrorMessage = "标题不能为空")]
[Display(Name = "标题")]
[StringLength(50)]
[MaxLength(50)]
public string Title { get; set; }

[Required(ErrorMessage = "请选择是否私有")]
[Display(Name = "相册是否私有?")]
public bool IsPrivate { get; set; }

[Display(Name = "访问码")]
[StringLength(16)]
[MaxLength(16)]
public string? AccessCode { get; set; }

[Display(Name = "上传相册封面图")]
[StringLength(255)]
[MaxLength(255)]
public string? ImageUrl { get; set; }

public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }

public int PhotographerId { get; set; }
[ValidateNever]
public Photographer Photographer { get; set; }

public int EventId { get; set; }
[ValidateNever]
public Event Event { get; set; }

[ValidateNever]
public IEnumerable<SelectListItem> PhotographerList { get; set; }
[ValidateNever]
public IEnumerable<SelectListItem> EventList { get; set; }

[ValidateNever]
public List<GalleryImage> GalleryImages { get; set; }

GalleryController - Upsert GET方法

public IActionResult Upsert(Guid? id)
{
    GalleryVM galleryVM = new GalleryVM
    {
        PhotographerList = _unitOfWork.Photographer.GetAll()
        .Select(p => new SelectListItem
        {
            Text = p.Name,
            Value = p.Id.ToString()
        }),

        EventList = _unitOfWork.Event.GetAll()
        .Select(e => new SelectListItem
        {
            Text = e.Name,
            Value = e.Id.ToString()
        }),
    };

    if (id == null || id == Guid.Empty)
    {
        return View(galleryVM);
    }
    else
    {
        var gallery = _unitOfWork.Gallery.Get(p => p.Id == id, includeProperties: "GalleryImages");

        if (gallery == null)
        {
            return NotFound();
        }

        galleryVM.Id = gallery.Id;
        galleryVM.Title = gallery.Title;
        galleryVM.IsPrivate = gallery.IsPrivate;
        galleryVM.AccessCode = gallery.AccessCode;
        galleryVM.ImageUrl = gallery.ImageUrl;
        galleryVM.CreatedAt = gallery.CreatedAt;
        galleryVM.UpdatedAt = gallery.UpdatedAt;
        galleryVM.PhotographerId = gallery.PhotographerId;
        galleryVM.EventId = gallery.EventId;
        galleryVM.GalleryImages = gallery.GalleryImages;

        return View(galleryVM);
    }
}

Upsert POST方法

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Upsert(GalleryVM galleryVM, IFormFile? singleFile, List<IFormFile> multipleFiles)
{
    // 验证模型状态
    if (ModelState.IsValid)
    {
        // 判断是创建还是更新
        if (galleryVM.Id == Guid.Empty)
        {
            // 单文件封面图上传逻辑
            string wwwRootPath = _webHostEnvironment.WebRootPath;

            if (singleFile != null)
            {
                string fileName = Path.GetFileName(singleFile.FileName);
                string galleryPath = Path.Combine(wwwRootPath, @"images\gallery");

                if (!string.IsNullOrEmpty(galleryVM.ImageUrl))
                {
                    // 更新时删除旧封面图
                    var oldImagePath = Path.Combine(wwwRootPath, galleryVM.ImageUrl.TrimStart('\\'));

                    if (System.IO.File.Exists(oldImagePath))
                    {
                        System.IO.File.Delete(oldImagePath);
                    }
                }

                using (var fileStream = new FileStream(Path.Combine(galleryPath, fileName), FileMode.Create))
                {
                    singleFile.CopyTo(fileStream);
                }

                galleryVM.ImageUrl = @"\images\gallery\" + fileName;
            }
            // 单文件上传逻辑结束

            // 创建Gallery
            var galleryObj = new Gallery();
            {
                galleryObj.Title = galleryVM.Title;
                galleryObj.IsPrivate = galleryVM.IsPrivate;
                galleryObj.AccessCode = galleryVM.IsPrivate ? galleryVM.AccessCode : null; // 非私有则清空访问码
                galleryObj.ImageUrl = galleryVM.ImageUrl;
                galleryObj.PhotographerId = galleryVM.PhotographerId;
                galleryObj.EventId = galleryVM.EventId;
                //galleryObj.GalleryImages = galleryVM.GalleryImages;
            }

            _unitOfWork.Gallery.Add(galleryObj);
            _unitOfWork.Save();
        }
        // 创建逻辑结束
        else
        {
            // 多文件上传逻辑开始
            string wwwRootPathMultiple = _webHostEnvironment.WebRootPath;

            if (multipleFiles != null)
            {
                foreach (IFormFile file in multipleFiles)
                {
                    string fileNameMultiple = Path.GetFileName(file.FileName);
                    string galleryPathMultiple = @"images\galleries\gallery-" + galleryVM.Id;
                    string finalPathMultiple = Path.Combine(wwwRootPathMultiple, galleryPathMultiple);

                    if (!Directory.Exists(finalPathMultiple))
                    {
                        Directory.CreateDirectory(finalPathMultiple);
                    }

                    using (var fileStream = new FileStream(Path.Combine(finalPathMultiple, fileNameMultiple), FileMode.Create))
                    {
                        file.CopyTo(fileStream);
                    }

                    GalleryImage galleryImage = new()
                    {
                        GalleryId = galleryVM.Id,
                        ImageUrl = @"\\" + galleryPathMultiple + @"\\" + fileNameMultiple,
                    };

                    if (galleryVM.GalleryImages == null)
                        galleryVM.GalleryImages = new List<GalleryImage>();

                    galleryVM.GalleryImages.Add(galleryImage);
                    _unitOfWork.Save();
                }
            }
            // 多文件上传逻辑结束

            // 更新Gallery
            var galleryObj = new Gallery();
            {
                galleryObj.Id = galleryVM.Id;
                galleryObj.Title = galleryVM.Title;
                galleryObj.IsPrivate = galleryVM.IsPrivate;
                galleryObj.AccessCode = galleryVM.IsPrivate ? galleryVM.AccessCode : null; // 非私有则清空访问码
                galleryObj.ImageUrl = galleryVM.ImageUrl;
                galleryObj.UpdatedAt = DateTime.Now;
                galleryObj.PhotographerId = galleryVM.PhotographerId;
                galleryObj.EventId = galleryVM.EventId;
                galleryObj.GalleryImages = galleryVM.GalleryImages;
            }
            _unitOfWork.Gallery.Update(galleryObj);
        }
        // 更新逻辑结束

        _unitOfWork.Save();

        return RedirectToAction(nameof(Index));
    }
    // 模型验证不通过返回视图
    return View(galleryVM);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:47:04