Home > Back-end >  Image uploading in sqlite database through web api
Image uploading in sqlite database through web api

Time:07-20

I'm creating a Web App in c# and I need to upload an image from an html form into my database.
I tried to do it this way but the binaryformatter can't be used in api controllers because of security issues.

[HttpGet("imageUploadEndpoint")]
    public IActionResult bytesImage([FromForm] object image)
    {
        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream ms = new MemoryStream();
        bf.Serialize(ms, image);
        //ms.ToArray() should then be uploaded to my sqlite database via entityframework in byte[] format 
        return Ok(ms.ToArray()); //this return was just to see what happened
    }

---IMAGE UPLOAD TO API RESOLVED---

Now I need to put images inside an sqlite db with entityframework. How could I do it?

CodePudding user response:

Uploading an image to a GET endpoint is not a good idea because they have no request body and are not supposed to change the server state (MDN).

Instead, I would recommend you to use a POST endpoint and data binding to IFormFileCollection. I am using this inside of a standard MVC controller but don't know whether it works in an ApiController, too.

[HttpPost("imageUploadEndpoint")]
public async Task<IActionResult> Upload(IFormFileCollection files)
{
    foreach (IFormFile file in files)
    {
        MemoryStream ms = new MemoryStream();
        await file.CopyToAsync(ms);
    }

    return Ok();
}

In one of my open source projects you can find the full implementation of an image upload with ASP.NET Core MVC (GitHub).

Update for storing in database

Although I would recommend to store photos as files, you could create an EF Core database context and an entity like this:

public class FileDbContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<File>().HasKey(f => f.Id);
    }
}

public class File
{
    public int Id { get; set; }
    public byte[] Data { get; set; }
}

Now you can extend your controller:

private readonly FileDbContext db; // Use constructor injection

[HttpPost("imageUploadEndpoint")]
public async Task<IActionResult> Upload(IFormFileCollection files)
{
    foreach (IFormFile file in files)
    {
        using MemoryStream ms = new MemoryStream();
        await file.CopyToAsync(ms);
        File dbFile = new File { Data = ms.ToArray() };
        db.Set<File>().Add(dbFile);
    }
    await db.SaveChangesAsync();

    return Ok();
}

CodePudding user response:

I solved the upload this way:

[HttpPost("endpoint")]
    public async Task<IActionResult> Upload(IFormFileCollection image)
    {
        using (MemoryStream fileStream = new MemoryStream()) //img object creation
        {
            await image[0].CopyToAsync(fileStream);
            var img = new { fileStream = fileStream.ToArray(), contentType = image[0].ContentType };
            return File(img.fileStream(), img.contentType)
        }
    }

and i'll put the img object in the sqlite db as a BLOB data value.

  • Related