1

I'm building an app in .NET 6 and React. I'm working on a feature to add images to the database.

So far, when uploading an image, it gets added to my desired folder with a specific name. However, when checking the users I can see that the imageFile column is null.

enter image description here

My client model file looks like this:

namespace NDereAPI.Models
{
    public partial class Klienti
    {
        public Klienti()
        {
            MyCarts = new HashSet<MyCart>();
        }

        public int KlientiId { get; set; }
        public string Name { get; set; } = null!;
        public string Surname { get; set; } = null!;
        public string Email { get; set; } = null!;
        public string Password { get; set; } = null!;
        public string PhoneNumber { get; set; } = null!;
        public string StreetName { get; set; } = null!;
        public string ZipCode { get; set; } = null!;
        public string City { get; set; } = null!;
        public string Role { get; set; } = null!;
        public string Picture { get; set; }

        [NotMapped]
        public IFormFile ImageFile { get; set; }

        public virtual ICollection<MyCart> MyCarts { get; set; }
    }
}

And my methods in the ClientController look like this:

[NonAction]
public async Task<string> SaveImage(IFormFile imageFile)
{
    string imageName = new String(Path.GetFileNameWithoutExtension(imageFile.FileName)
            .Take(10).ToArray()).Replace(' ', '-');
    imageName = imageName + DateTime.Now.ToString("yymmssfff") + Path.GetExtension(imageFile.FileName);

    var imagePath = Path.Combine(_hostEnvironment.ContentRootPath, "Images", imageName);

    using (var fileStream = new FileStream(imagePath, FileMode.Create))
    {
        await imageFile.CopyToAsync(fileStream);
    }

    return imageName;
}

[HttpPost]
public async Task<ActionResult<List<Klienti>>> AddClient([FromForm] Klienti klient)
{
    klient.Picture = await SaveImage(klient.ImageFile);
    dataContext.Klientet.Add(klient);
    await dataContext.SaveChangesAsync();

    return Ok(await dataContext.Klientet.ToListAsync());
}

Note: the Picture column is just the name of the saved image.

What am I doing wrong? Let me know if I should provide more info about this problem.

Also, I would love a recommendation on a tutorial about storing images in the database for .NET 6 and React. I haven't stumbled upon the perfect source yet...

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459

2 Answers2

2

In your code, ImageFile is [NotMapped] in class Klienti. The [NotMapped] attribute is used to specify that an entity or property is not to be mapped to a table or column in the database. That's why Entity Framework is ignoring this and not storing in Database.

r0-
  • 2,388
  • 1
  • 24
  • 29
SmartCoder
  • 856
  • 6
  • 11
  • Doing that, I get this error: "InvalidOperationException: The property 'Klienti.ImageFile' is of an interface type ('IFormFile')." The tutorial I followed showed this method of using [NotMapped]. Also, as an update, using the Post method on Swagger actually shows the image file object when returning the posted object, but when using the Get method to see all the clients, the ImageFile column is still null. – Dren Ibrahimi Jun 19 '22 at 12:08
-1

You will need to convert your file to a encoded byte array and then to string to save it. See this SO post Convert posted file to byte array

The not mapped file field can be a string or may be byte array and must be given value by programming the way image path is added to picture field.

  • While images and other binary-content _can_ be stored in a database using `varbinary` columns, it’s still not a good idea to store binary files larger than a couple hundred bytes in a database table because it invariably introduces a significant IO bottleneck, which is why I downvoted this answer (I.e. for being bad advice). The other reason for downvoting this answer is because _EF entity classes should not be used as DTOs_ for far too many reasons to give here. – Dai Jun 29 '22 at 09:59
  • Also, Base64-encoding binary files is horrible: don’t do it. There are very few legitimate reasons to Base64-encode a file in the browser and none of them apply here: **it is not necessary** to Base64-encode a file to upload it nor to store it in a database, nor for using HTML canvas (use to/fromBlob instead). – Dai Jun 29 '22 at 10:01
  • Its not for us to judge if storing file in db or using EF for any purpose is a good practice or not. For whatever reason, if he wants to save, thats the way to do it. Is my answer wrong, is there a different and better way to do it? What if he wants to store some other binary data? It would be good if you could put some real link to back up your claims. – Vikash Agrawal Jul 02 '22 at 04:33