Building a File Upload API in .NET
Creating a file upload API is a common feature for many web applications, especially those that require users to submit documents, images, or other media files. In this article, we will guide you through building a secure and efficient file upload API in .NET Core. You’ll learn how to set up your project, handle incoming files, and store them securely, ensuring that your application can manage user-uploaded content reliably.
Prerequisites
- .NET 8
Setup project
dotnet new webapi -o dotnet_api -n App
Project structure
├─ App.csproj
├─ Program.cs
├─ Controllers
│ └─ ProductController.cs
├─ Models
│ └─ Product.cs
└─ wwwroot
└─ index.html
Project files
App.csproj
This file is the .NET project configuration file. We don't use any additional packages for this project.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
Program.cs
This file sets up a basic ASP.NET Core web application. It configures the application to use controllers, serve static files, and handle routing, then runs the application.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting();
app.MapControllers();
app.Run();
Product.cs
The Product
model is a simple class used for testing file uploads in an ASP.NET Core application. This model is typically used to bind data from a form submission, where the product name and an image file are provided.
namespace App.Models
{
public class Product
{
public string Name { get; set; }
public IFormFile Image { get; set; }
}
}
ProductController.cs
This .NET controller handles file uploads in an ASP.NET Core MVC application.
using Microsoft.AspNetCore.Mvc;
namespace App.Controllers
{
public class ProductController : Controller
{
[HttpPost("submit")]
public IActionResult Submit([FromForm] Models.Product model)
{
var uploadPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/uploads");
if (!Directory.Exists(uploadPath)) {
Directory.CreateDirectory(uploadPath);
}
var filePath = Path.Combine(uploadPath, model.Image.FileName);
using (var target = new FileStream(filePath, FileMode.Create)) {
model.Image.CopyTo(target);
}
return Ok(new {
Name = model.Name,
Image = model.Image.FileName
});
}
}
}
The Submit
action accepts a Product
model via a POST request. It checks if the uploads directory exists and creates it if necessary. The uploaded file is then saved to this directory using the file's original name. Finally, the method returns a JSON response containing the product's name and the uploaded file's name.
index.html
This HTML form is designed for users to upload a product name along with an associated image file.
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/css/bootstrap.min.css" rel="stylesheet">
<script>
function submitForm() {
let form = document.getElementById('form')
let data = new FormData(form)
fetch('submit', {
method: 'POST',
body: data
}).then(res => {
res.json().then(result => {
let alert = document.getElementById('alert')
alert.children[0].innerText = `Upload success!\nName: ${result.name}\nImage: ${result.image}`
alert.children[1].src = `/uploads/${result.image}`
alert.classList.remove('d-none')
form.reset()
})
})
return false
}
</script>
</head>
<body>
<div class="container">
<div class="row mt-3">
<form id="form" onsubmit="return submitForm()">
<div class="mb-3 col-12">
<label class="form-label" for="name">Name</label>
<input id="name" name="Name" class="form-control form-control-sm" required />
</div>
<div class="mb-3 col-12">
<label class="form-label" for="image">Image</label>
<input type="file" accept="image/*" id="image" name="Image" class="form-control form-control-sm" required />
</div>
</div>
<div class="col-12">
<button class="btn btn-sm btn-primary">Submit</button>
</div>
</form>
<div id="alert" class="alert alert-success mt-3 d-none">
<p></p>
<img id="img" width="200px" />
</div>
</div>
</div>
</body>
</html>
The form is set to submit via a JavaScript function, submitForm()
, which is triggered on form submission. Additionally, there is a hidden alert section that can display the uploaded image and a success message after submission successfully.
Run project
dotnet run
Open the web browser and goto http://localhost:5122
You will find this test page.
Testing
Enter the name in the input field and browse for a file to upload.
Click the submit button to send the form. You will then see a success message along with the submitted information returned from our API.
Conclusion
In essence, ASP.NET Core simplifies the process of managing file uploads in .NET applications. By leveraging a basic controller and form, you can efficiently process uploads and enhance the overall user experience in your web application projects.
Source code: https://github.com/stackpuz/Example-File-Upload-dotnet-8
Create a CRUD Web App in Minutes: https://stackpuz.com