0

I'm using ASP.NET Core MVC, C# and EF Core code-first.

I'm running into an issue that is not allowing me to upload multiple files to my folder and the corresponding path to the database table. The file input that handles the multiple image upload is called GalleryImages and the code that handles the multiple file upload is listed below under the comment // Start multipleFile Upload Image Code.

I'm having trouble getting the newly created Gallery Id value from the initial Create method from the code listed below // Create Gallery.

When a user fills out the form they will need to upload multiple files to the folder path and the folder path needs added to the database, but I need to retrieve the Gallery Id value in order to perform this step.

I can only get the multiple file images to work properly during the Edit process once the Gallery ID has been established.

I have tried to move the multiple image upload code around in different areas but have had no luck no matter were I place the code.

Model classes:

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; }
}
public class GalleryImage
{
    public int Id { get; set; }
    public string? ImageUrl { get; set; }

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

View model class:

public Guid Id { get; set; }

[Required(ErrorMessage = "Title is required")]
[Display(Name = "Title")]
[StringLength(50)]
[MaxLength(50)]
public string Title { get; set; }

[Required(ErrorMessage = "IsPrivate is required")]
[Display(Name = "Gallery is Private?")]
public bool IsPrivate { get; set; }

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

[Display(Name = "Upload Gallery Image")]
[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 code:

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 code:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Upsert(GalleryVM galleryVM, IFormFile? singleFile, List<IFormFile> multipleFiles)
{
    // Start Model State IsValid
    if (ModelState.IsValid)
    {
        // Start check if Id value is null or exist
        if (galleryVM.Id == Guid.Empty)
        {
            // Start singleFile Upload Image Code
            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))
                {
                    // Delete old singleFile image if needed on update
                    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;
            }
            // End singleFile Upload Image Code

            // Create Gallery
            var galleryObj = new Gallery();
            {
                galleryObj.Title = galleryVM.Title;
                galleryObj.IsPrivate = galleryVM.IsPrivate;
                galleryObj.AccessCode = galleryVM.IsPrivate ? galleryVM.AccessCode : null; // Clear AccessCode if not private
                galleryObj.ImageUrl = galleryVM.ImageUrl;
                galleryObj.PhotographerId = galleryVM.PhotographerId;
                galleryObj.EventId = galleryVM.EventId;
                //galleryObj.GalleryImages = galleryVM.GalleryImages;
            }

            _unitOfWork.Gallery.Add(galleryObj);
            _unitOfWork.Save();
        }
        // End check if Id value is null or exist
        else
        {
            // Start multipleFile Upload Image Code
            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();
                }
            }
            // End multipleFile Upload Image Code

            // Update Gallery
            var galleryObj = new Gallery();
            {
                galleryObj.Id = galleryVM.Id;
                galleryObj.Title = galleryVM.Title;
                galleryObj.IsPrivate = galleryVM.IsPrivate;
                galleryObj.AccessCode = galleryVM.IsPrivate ? galleryVM.AccessCode : null; // Clear AccessCode if not private
                galleryObj.ImageUrl = galleryVM.ImageUrl;
                galleryObj.UpdatedAt = DateTime.Now;
                galleryObj.PhotographerId = galleryVM.PhotographerId;
                galleryObj.EventId = galleryVM.EventId;
                galleryObj.GalleryImages = galleryVM.GalleryImages;
            }
            _unitOfWork.Gallery.Update(galleryObj);
        }
        // End check if Id value is null or exist

        _unitOfWork.Save();

        return RedirectToAction(nameof(Index));
    }
    // End Model State IsValid

    return View(galleryVM);
}
10
  • for the "CopyTo()" methods I believe you can just pass a bool of true as second argument to overwrite a file, so you can remove the old file/delete logic. You could probably just bind to the List<IFormFile> there too? (It should always come in through Request.Files so should already be a list... so you can remove single file logic too methinks) For your main question you can get the primary key for the gallery image record after you write the record to the DB. (right now it looks like you have GalleryID, which is not unique marked as "guid" which seems like it should be unique...) Commented Sep 13 at 16:18
  • So, is "Id" the primary key for each gallery image? Commented Sep 13 at 16:21
  • @browsermator, The Gallery Model has an Id that is Guid. The GalleryImage Model has an Id of int (no guid) value for Id in the GalleryImage Model. Commented Sep 13 at 16:23
  • I've always left it up to the DB to create the primary key, so I'm not so sure about using Guid type there. Commented Sep 13 at 16:28
  • @browsermator, my initial thought was that I would be able to capture the Guid Id from the Gallery Model after the creation took place. I start with the multiple image upload on the line labeled // Start multipleFile Upload Image Code on the Upsert Post Code. Commented Sep 13 at 16:28

0