We are going to discuss single file uploads with the help of the IFormFile Interface and others that are provided by .NET and step-by. y-step, i.e .NET Core 7 Minimal API.
Introduction
.NET Core 7 brings a new way to create APIs that are lightweight and easy to use. These APIs are called Minimal APIs, and they make building APIs simpler and faster.
In this article, we'll learn how to use Minimal APIs to create a file upload feature. This means we can easily upload files like images or documents to our server using a simple API.
Prerequisites
- .NET Core 7 SDK
- Visual Studio 2022
- Postman
Creating a New Project in Visual Studio
Creating a New Project in Visual Studio 2022 Start the Visual Studio software and select "Create a new project."
The code snippet app.MapGet("/", () => "Hello World!"); sets up a minimal API endpoint that responds with "Hello World!" when you send a GET request to the root ("/") URL.
And run applications to build swagger UI for testing minimal API endpoints.
Running the application with Swagger UI will allow you to test the minimal API endpoints interactively. Swagger UI provides a user-friendly interface for exploring and testing the endpoints of your API. It generates documentation for your API based on metadata and allows users to interact with the API directly from their web browser.
Implementation for FileUpload MinimalAPI
app.MapPost("/FileUpload", async (HttpContext context, string location, IFileUpladService fileUpladService) =>
{
var form = await context.Request.ReadFormAsync();
var files = form.Files;
var file = files.Any() && files.Count > 0 ? files[0] : null;
var response = await fileUpladService.FileUpload(file, location, context);
return Results.Created("FileUrl", response);
});
app.MapPost("/FileUpload", async (HttpContext context, string location, IFileUploadService fileUploadService) =>
{
// This line defines a POST endpoint at "/FileUpload". It takes three parameters: context, location, and file upload service.
var form = await context.Request.ReadFormAsync();
// This line reads the form data from the request asynchronously.
var files = form.Files;
// This line extracts the files from the form data.
var file = files.Any() && files.Count > 0 ? files[0] : null;
// This line checks if there are any files in the request. If so, it selects the first file; otherwise, it sets the file to null.
var response = await fileUploadService.FileUpload(file, location, context);
// This line calls a method named FileUpload on the fileUploadService object. It passes the file, location, and context as parameters, and awaits the response.
return Results.Created("FileUrl", response);
// This line returns a response with status code 201 (Created). It includes the file upload response as the data and sets the location header to "FileUrl".
});
public class FileUpladService : IFileUpladService
{
private readonly IWebHostEnvironment _webHostEnvironment;
public FileUpladService(IWebHostEnvironment webHostEnvironment)
{
this._webHostEnvironment = webHostEnvironment;
}
public async Task<string> FileUpload(IFormFile file, string Location, HttpContext context)
{
string WebPhotoPath = "";
if (file != null && file.Length > 0)
{
var fileName = Path.GetFileName(file.FileName);
string uploadFolder = Path.Combine(this._webHostEnvironment.WebRootPath, @"Uploads\");
string uploadPath = Path.Combine(uploadFolder + DateTime.Now.ToString("MMyyyy") + @"\");
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
fileName = Location + "." + Path.GetExtension(fileName);
var filePath = Path.Combine(
uploadPath,
fileName
);
using (Stream fileStream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
WebPhotoPath = "https://" + context.Request.Host.Value + @"\Uploads\" + DateTime.Now.ToString("MMyyyy") + @"\" + fileName;
}
return WebPhotoPath;
}
}
public FileUploadService(IWebHostEnvironment webHostEnvironment)
{
this._webHostEnvironment = webHostEnvironment;
}
This is the constructor of the class. It accepts an IWebHostEnvironment parameter, which is used to access the web hosting environment. It's injected into the class using dependency injection.
public async Task<string> FileUpload(IFormFile file, string Location, HttpContext context)
{
}
This method handles the file upload process. It takes three parameters.
- file: The file to be uploaded.
- Location: The location where the file should be saved.
- context: The HTTP context, which provides access to the request and response objects.
I have completed the development of the file upload minimal API, and I am now testing it using Postman.
The API response URL doesn't work in the browser because we haven't configured the UseStaticFiles() middleware yet. Once we configure it, the images will be displayed correctly.
///minimal_API:
app.MapGet("/", () => "Hello World!");
app.MapPost("/FileUpload", async (HttpContext context, string location,IFileUpladService fileUpladService) =>
{
var form = await context.Request.ReadFormAsync();
var files = form.Files;
var file = files.Any() && files.Count > 0 ? files[0] : null;
var response = await fileUpladService.FileUpload(file, location, context);
return Results.Created("FileUrl",response);
});
app.UseCors("CorsPolicy");
app.UseHttpsRedirection();
app.UseAuthorization();
app.UseStaticFiles();
app.MapControllers();
app.Run();
app.UseStaticFiles(); in program .cs file.
Finally, the image will be displayed in the browser.
.NET Core Minimal API Source Link: https://github.com/jobin4jo/Minimal_API_With_File_Upload.
Conclusion
.NET Core 7's Minimal APIs provide an easy and fast way to build lightweight APIs. By using Minimal APIs, developers can quickly add features like file uploads to their applications. This article has shown how Minimal APIs simplify the process of implementing file upload functionality, making applications more user-friendly and efficient.
Happy Learning!