0

I am trying to understand the following problem, for what I created a minimal test application:

A html file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <button title="Click me" value="Click me" onclick="onClickHandler()" />
    <script type="text/javascript">
        async function onClickHandler() {
            let input = document.createElement('input');
            input.type = 'file';
            input.onchange = async (_) => {
                
                if(!input.files || input.files.length === 0) return;

                const result = await postFileAsync(input.files[0]);
            };

            input.click();
            }

        async function postFileAsync(file)
        {
            const headers = new Headers();
            //headers.append('Content-Type', 'multipart/form-data');

            const formData = new FormData();           
            formData.append("file", file);

            const endpointUrl = "https://localhost:5001/v1/upload";

            const result = await fetch(endpointUrl, {
                method: 'POST', 
                cache: 'no-cache',
                headers: headers,
                body: formData
                });
                if (result.ok) {
                try {
                    return { data: await result.json(), status: result.status };
                } catch (error) {
                    return { status: result.status };
                }
            }
            return { status: result.status };
        }

    </script>
</body>
</html>

A minimal api in asp.net core 7:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.MapPost("v1/upload", async ([FromForm]IFormFile file) =>
{
    string tempfile = CreateTempfilePath();
    using var stream = File.OpenWrite(tempfile);
    await file.CopyToAsync(stream);

    // dom more fancy stuff with the IFormFile
});

app.MapPost("v2/stream", async (Stream body) =>
{
    string tempfile = CreateTempfilePath();
    using var stream = File.OpenWrite(tempfile);
    await body.CopyToAsync(stream);
});

app.MapPost("v3/stream", async (PipeReader body) =>
{
    string tempfile = CreateTempfilePath();
    using var stream = File.OpenWrite(tempfile);
    await body.CopyToAsync(stream);
});

app.MapPost("/uploadmany", async (IFormFileCollection myFiles) =>
{
    foreach (var file in myFiles)
    {
        string tempfile = CreateTempfilePath();
        using var stream = File.OpenWrite(tempfile);
        await file.CopyToAsync(stream);

        // dom more fancy stuff with the IFormFile
    }
});

string CreateTempfilePath()
{
    var filename = $"{Guid.NewGuid()}.tmp";
    var directoryPath = Path.Combine("temp", "uploads");
    if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);

    return Path.Combine(directoryPath, filename);
}


app.Run();

Now what I do not understand, if I comment out in the js code the following code:

headers.append('Content-Type', 'multipart/form-data');

it never hit's the controllers v1/upload endpoint, if I comment out it hits.

Or what would be a best solution? thnx

P. Magnusson
  • 82
  • 2
  • 9
Wasyster
  • 2,279
  • 4
  • 26
  • 58

1 Answers1

0

After test your code, I found the payload like below.

enter image description here

With

headers.append('Content-Type', 'multipart/form-data');

it didn't contain boundary.

So I did some searching in this direction and found a very good explanation in this blog, you can refer to it.

Uploading files using 'fetch' and 'FormData'

Jason Pan
  • 15,263
  • 1
  • 14
  • 29