Proper Handling of File Uploads with ASP.NET Core and Swagger


When developing APIs with ASP.NET Core, handling file uploads is a common requirement. When combined with automatic API documentation provided by Swagger, some challenges may arise. In this article, we’ll explore how to correctly configure your API to handle file uploads and ensure that Swagger documents it properly.

Prerequisites

  • Visual Studio 2022 or Visual Studio Code
  • .NET 6 SDK or later
  • Basic knowledge of ASP.NET Core

Step 1: Create a New ASP.NET Core Web API Project

First, create a new ASP.NET Core Web API project. You can do this from the command line:

dotnet new webapi -n FileUploadDemo
cd FileUploadDemo

Step 2: Install Required Packages

Make sure you have the latest version of Swashbuckle.AspNetCore installed. Run the following command:

dotnet add package Swashbuckle.AspNetCore --version 6.7.3

Step 3: Configure Swagger in Program.cs

Ensure your Program.cs file has the correct configuration for Swagger:

using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "File Upload API", Version = "v1" });
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

Step 4: Create the File Upload Controller

Create a new controller called FileUploadController.cs in the Controllers folder:

using Microsoft.AspNetCore.Mvc;

namespace FileUploadDemo.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class FileUploadController : ControllerBase
    {
        private readonly ILogger<FileUploadController> _logger;

        public FileUploadController(ILogger<FileUploadController> logger)
        {
            _logger = logger;
        }

        [HttpPost("upload")]
        [Consumes("multipart/form-data")]
        public async Task<IActionResult> UploadFile(IFormFile file)
        {
            if (file == null || file.Length == 0)
                return BadRequest("File is empty");

            // Normally, you would save the file somewhere
            // For now, we'll just log information about the file
            _logger.LogInformation($"Received file {file.FileName} - size: {file.Length} bytes");

            var filePath = Path.GetTempFileName();
            using (var stream = System.IO.File.Create(filePath))
            {
                await file.CopyToAsync(stream);
            }

            return Ok(new { fileName = file.FileName, size = file.Length, path = filePath });
        }
    }
}

Key points to note:

  1. We use the [Consumes("multipart/form-data")] attribute to indicate that this endpoint accepts multipart form data.
  2. We don’t use [FromForm] on the IFormFile parameter. ASP.NET Core automatically infers that it should be bound from the form.
  3. We perform basic validation to ensure a file has been sent.

Step 5: Test the API

  1. Run the application with dotnet run.
  2. Open a browser and go to https://localhost:7001/swagger (the port may vary).
  3. You should see the Swagger UI with your file upload endpoint.
  4. Test the endpoint using the Swagger interface:
  • Click on the POST /api/FileUpload/upload endpoint.
  • Click «Try it out».
  • Use the «Choose File» button to select a file.
  • Click «Execute» to send the request.

Additional Considerations

Handling Multiple Files

If you need to handle multiple files or additional parameters, you can create a binding model:

public class FileUploadModel
{
    public IFormFile File { get; set; }
    public string AdditionalInfo { get; set; }
}

[HttpPost("upload-with-info")]
[Consumes("multipart/form-data")]
public async Task<IActionResult> UploadFileWithInfo([FromForm] FileUploadModel model)
{
    if (model.File == null || model.File.Length == 0)
        return BadRequest("File is empty");

    _logger.LogInformation($"Received file {model.File.FileName} with additional info: {model.AdditionalInfo}");

    // Process the file here

    return Ok(new { fileName = model.File.FileName, additionalInfo = model.AdditionalInfo });
}

Size Limitations

By default, ASP.NET Core limits request sizes to 30 MB. If you need to allow larger files, you can configure this in Program.cs:

builder.Services.Configure<IISServerOptions>(options =>
{
    options.MaxRequestBodySize = int.MaxValue;
});

builder.Services.Configure<KestrelServerOptions>(options =>
{
    options.Limits.MaxRequestBodySize = int.MaxValue;
});

Conclusion

Handling file uploads in ASP.NET Core and documenting them correctly with Swagger is quite straightforward once you understand the key details. Always remember to check the official documentation for the most up-to-date information, as best practices may change with new versions of the framework.

Happy coding!

References

Deja un comentario

Este sitio utiliza Akismet para reducir el spam. Conoce cómo se procesan los datos de tus comentarios.