In contemporary web applications, it is frequently necessary to upload files. Whether it involves uploading images, documents, or any other file format, ensuring a seamless user experience when dealing with uploads is crucial. This article will delve into the process of incorporating file upload functionality into an ASP.NET Core Web API.

Setting up the Project

To begin, we will set up a new ASP.NET Core Web API project. We'll also install the necessary NuGet packages required for file handling, such as
    Microsoft.EntityFrameworkCore.SqlServer
    Microsoft.EntityFrameworkCore
    Microsoft.EntityFrameworkCore.Tools


The tools which have been leveraged for this tutorial are.
    Visual Studio Community Edition 16.4.5
    .NET 6.0
    Entity Framework Core
    Web API

The entire source code can be downloaded from GitHub.

Creating the Model and Database Context
In this section, we'll define the model class representing the uploaded files and the corresponding database context for storing the file data. We'll use Entity Framework Core to interact with the database and store the file information as byte arrays.

Create a model class to represent the image entity. In this example, let's call it ImageEntity.cs:
public class ImageEntity
{
    [Key]
    public int Id { get; set; }

    public string FileName { get; set; }

    public byte[] Data { get; set; }
}

Then, create a database context class, AppDbContext.cs, that inherits from DbContext and includes a DbSet for the ImageEntity:
public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options)
        : base(options)
    {
    }

    public DbSet<ImageEntity> Images { get; set; }
}


Handling Multiple File Uploads in the Controller
In this segment, we will develop a controller action that receives an IFormFile object to manage file uploads. We will extract the file data and store it in the database utilizing the database context.

Create a controller, ImagesController.cs, with two actions: one for uploading the file and another for retrieving the file:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace FileUploadsPOC.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ImagesController : ControllerBase
    {
        private readonly AppDbContext _dbContext;


        public ImagesController(AppDbContext dbContext)
        {
            _dbContext = dbContext;

        }

        [HttpPost("upload")]
        public async Task<IActionResult> Upload(IFormFile file)
        {
            if (file == null || file.Length == 0)
                return BadRequest("No file uploaded.");

            var imageEntity = new ImageEntity
            {
                FileName = file.FileName
            };

            using (var memoryStream = new MemoryStream())
            {
                await file.CopyToAsync(memoryStream);
                imageEntity.Data = memoryStream.ToArray();
            }

            await _dbContext.Images.AddAsync(imageEntity);
            await _dbContext.SaveChangesAsync();

            return Ok(imageEntity.Id);
        }

        [HttpGet("download/{id}")]
        public async Task<IActionResult> Download(int id)
        {
            var imageEntity = await _dbContext.Images.FirstOrDefaultAsync(image => image.Id == id);

            if (imageEntity == null)
                return NotFound();

            var fileContentResult = new FileContentResult(imageEntity.Data, "application/octet-stream")
            {
                FileDownloadName = imageEntity.FileName
            };

            return fileContentResult;
        }
    }
}

Setup the configuration
Make sure to configure your database connection string in the appsettings.json file:
"ConnectionStrings": {
    "DefaultConnection": "Server=localhost;Database=FileUploadPOC;Trusted_Connection=SSPI;Encrypt=false;TrustServerCertificate=true"
  }

Configure your database connection and add the required services to Program.cs
builder.Services.AddDbContext<AppDbContext>(options =>
            options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

Create the Database Migration and Update Database
Open the Package Manager Console and execute the below commands.

Add-Migration FileUpload (FileUpload is the name of the migration, you can provide any name at your convenience)

Once the build succeeds, execute the below command.
Update-database

Testing the Upload and Download Functionality
To ensure our file upload functionality works as expected, we'll test it using a tool like Postma. I will leave this to you.

Following the steps outlined in this blog post, you can easily enable this feature in your web applications. Happy coding!