.netasp.net-coreswaggerwebapinswag

NSwag produces incorrect output for IFromFile in Minimal API when file parameter is wrapped in model class


I’m working on a .NET 8 Minimal API (web) project and using NSwag for generating Swagger documentation. I have an endpoint that accepts a file upload, and the file parameter is wrapped inside a model class. However, the generated Swagger documentation does not correctly represent the file parameter. Here’s a simplified version of my code:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="NSwag.AspNetCore" Version="14.1.0" />
  </ItemGroup>

</Project>
public class FileUploadModel
{
    public IFormFile File { get; set; }
}
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddOpenApiDocument(config =>
{
    config.DocumentName = "Test";
    config.Title = "Test v1";
    config.Version = "v1";
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseOpenApi();
    app.UseSwaggerUi(config =>
    {
        config.DocumentTitle = "Test";
        config.Path = "/swagger";
        config.DocumentPath = "/swagger/{documentName}/swagger.json";
        config.DocExpansion = "list";
    });
}

app.MapPost("/upload", ([FromForm] FileUploadModel model) =>
{
    // Handle file upload
    return Results.Ok();
});

app.Run();

In the generated Swagger UI, the File parameter is not shown as a file upload input but as a regular string input. This is causing issues with clients trying to use the API.

What I’ve tried:

  1. Ensuring that NSwag is correctly configured in my project.
  2. Checking the generated OpenAPI specification to see if the file type is correctly identified.
  3. Searching for similar issues online but haven’t found a solution that works.

My question is: How can I configure NSwag to correctly generate the Swagger documentation for an IFormFile parameter when it is wrapped inside a model class in a Minimal API project?

Any help or pointers would be greatly appreciated!


Solution

  • Change [FromForm] to [AsParameters]. Here is my test code.

    app.MapPost("/upload", ([AsParameters] FileUploadModel model) =>
    {
        // Handle file upload
        return Results.Ok();
    }).DisableAntiforgery();
    // if you have Antiforgery validation, please check related docs
    

    Test Result

    enter image description here

    Related links

    1. Binding to forms

    2. Using IFormFile in complex objects

    enter image description here

    enter image description here