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.