Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I do file upload using ASP.NET Core 6 minimal api?

I want to create a simple file upload endpoint in ASP.NET Core 6 and thought it would be as easy as described here https://dotnetthoughts.net/handling-file-uploads-in-openapi-with-aspnet-core/.

When I have an endpoint defined like:

app.MapPost("/upload", (IFormFile file) =>
{
    //Do something with the file
    return Results.Ok();
}).Accepts<IFormFile>("multipart/form-data").Produces(200);

I get a 415 back when I call the endpoint. The message I get back is something like:

Expected a supported JSON media type but got "multipart/form-data; ...

Not sure why it expected a supported json when I say that the endpoint should accept multipart/form-data.

Any ideas or thoughts on what to do here?

like image 705
Tomas Jansson Avatar asked Jan 21 '26 20:01

Tomas Jansson


2 Answers

Currently out of the box support for binding in Minimal APIs is quite limited. Supported binding sources:

  • Route values
  • Query string
  • Header
  • Body (as JSON)
  • Services provided by dependency injection
  • Custom

NOTE: Binding from forms is not natively supported in .NET 6

You can either leverage custom binding or use special types handling:

app.MapPost("/upload", (HttpRequest request) =>
{
    //Do something with the file
    var files = request.Form.Files;
    return Results.Ok();
})
.Accepts("multipart/form-data")
.Produces(200);

UPD

Since .net-7.0 Minimal APIs should be able to bind IFormFile/IFormFileCollection directly:

app.MapPost("/upload", async (IFormFile file) =>
{
    // ...
});

app.MapPost("/upload_many", async (IFormFileCollection myFiles) =>
{
    foreach (var file in myFiles)
    {
        // ...
    }
});
like image 158
Guru Stron Avatar answered Jan 24 '26 13:01

Guru Stron


Just noting here, you can upload a file with any ContentType like the following sample code.

In this example I chose a text/plain ContentType, but you can choose your own by editing the .Accepts<IFormFile>("text/plain"); line to your desired ContentType.

app.MapPost("/upload",
    async (HttpRequest request) =>
    {
        using (var reader = new StreamReader(request.Body, System.Text.Encoding.UTF8))
        {

            // Read the raw file as a `string`.
            string fileContent = await reader.ReadToEndAsync();

            // Do something with `fileContent`...
    
            return "File Was Processed Sucessfully!";
        }
    }).Accepts<IFormFile>("text/plain");

It is also well supported by Swagger UI:

enter image description here

like image 38
Tal Jacob - Sir Jacques Avatar answered Jan 24 '26 13:01

Tal Jacob - Sir Jacques