Best practice for saving image in database

Rafael Massula 61 Reputation points
2022-01-04T00:53:17.627+00:00

Hi guys!
I have a lot of doubts about like saving images in database. I have a project in Asp Net Core, with somes models and i would like saving product with a list images. I thought using base64, but not know if good idea. Some sugestion? Remembiring that is a complex model i need to receive:
{
"Description": "Strogonoff de frango sem glúten/ lactose",
"Price": 17.90,
"Size": 300,
"ManufactoringDate": "2021-12-26",
"Files":[
{
"Bytes": "base64",
"Description": "prato-principal",
"FileExtension": ".png",
"Size": 26498
}
]
}

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,148 questions
SQL Server
SQL Server
A family of Microsoft relational database management and analysis systems for e-commerce, line-of-business, and data warehousing solutions.
12,666 questions
0 comments No comments
{count} votes

Accepted answer
  1. Zhi Lv - MSFT 32,011 Reputation points Microsoft Vendor
    2022-01-04T05:54:26.277+00:00

    Hi @Rafael Massula ,

    Base on your previous question, you can configure one-to-many relationship between the Product and Photo table, then we can add/update/delete the related entities via the navigation property. More detail information see Relationships.

    So, I suggest you could add the navigation property in the Product model. Code like this:

    public class Product  
    {   
        [Key]  
        public int Id { get; set; }   
        [Required]  
        public string Description { get; set; }   
        [Required]  
        public decimal Price { get; set; }   
        [Required]  
        public int Size { get; set; }   
        [Required]  
        public DateTime ManufactoringDate { get; set; }   
        [Required]  
        public DateTime ExpirationDate { get; set; }  
    
        //navigation property: configure one-t0-many relationship with Photo   
        public List<Photo> Photos { get; set; }  
    
        [FromForm]  
        [NotMapped]  
        public IFormFileCollection Files { get; set; }   
    }  
    public class Photo  
    {  
        [Key]  
        public int Id { get; set; }  
        public byte[] Bytes { get; set; }  
        public string Description { get; set; }  
        public string FileExtension { get; set; }  
        public decimal Size { get; set; }  
        public int ProductId { get; set; }  
        [ForeignKey("ProductId")]  
        public Product Product { get; set; }  
    }  
    

    Then, in the action method: you can refer to the following sample to create product.

        [HttpGet]  
        public IActionResult CreateProduct()  
        {  
            return View();  
        }  
        [HttpPost]  
        public async Task<IActionResult> CreateProductAsync([FromForm]Product product)  
        {  
            if (!ModelState.IsValid)  
                return (IActionResult)Task.FromResult(product);  
            //create a new Product instance.  
            Product newproduct = new()  
            {  
                Description = product.Description,  
                Price = product.Price,  
                Size = product.Size,  
                ManufactoringDate = product.ManufactoringDate  
            };  
    
            //create a Photo list to store the upload files.  
            List<Photo> photolist = new List<Photo>();  
            if (product.Files.Count > 0)  
            {  
                foreach(var formFile in product.Files)  
                {  
                    if (formFile.Length > 0)  
                    {    
                        using (var memoryStream = new MemoryStream())  
                        {  
                            await formFile.CopyToAsync(memoryStream);  
                            // Upload the file if less than 2 MB  
                            if (memoryStream.Length < 2097152)  
                            {  
                                //based on the upload file to create Photo instance.  
                                //You can also check the database, whether the image exists in the database.  
                                var newphoto = new Photo()  
                                {  
                                    Bytes = memoryStream.ToArray(),  
                                    Description = formFile.FileName,  
                                    FileExtension = Path.GetExtension(formFile.FileName),  
                                    Size = formFile.Length,                                      
                                };  
                                //add the photo instance to the list.  
                                photolist.Add(newphoto);  
                            }  
                            else  
                            {  
                                ModelState.AddModelError("File", "The file is too large.");  
                            }  
                        }  
                    }  
                }  
            }  
            //assign the photos to the Product, using the navigation property.  
            newproduct.Photos = photolist;  
    
            _context.Products.Add(newproduct);  
            _context.SaveChanges();  
             
    
            return View();  
        }  
    

    The result is like this: we can see that, even though we just add the product the to the Product table, since we have configure relationship via the navigation property, the relates photo will also add to the Photo table.

    162114-2.gif

    Finally, you can refer the Loading Related Data to load the related entities.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Dillion

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Martin Cairney 2,241 Reputation points
    2022-01-04T02:34:03.69+00:00

    You can either consider the use of the VARBINARY(MAX) datatype to store images directly in the data base or have a look at FILESTREAM which can let you store the image files outside the database but with access and controls via SQL Server itself.

    0 comments No comments