ASP.NET Minimal API を使用したファイルのアップロード


.net 6 のリリースで、私は Minimal APIs で遊ぶことに非常に興奮しました.

私が最初に行ったことの 1 つは、既存のプロジェクトを .net 6 に移行し、コントローラーを最小限の API に変換することでした.

プロセスは簡単だと思いましたが、アップロード エンドポイントのテストが失敗したときは驚きました.

Minimal API Endpoint に変換した後の私の実装はこれでした. 👇

app.MapPost("/upload",
    async Task<IResult>(IFormFile request) =>
    {
        if (request.Length == 0)
            return Results.BadRequest();

        await using var stream = request.OpenReadStream();

        var reader = new StreamReader(stream);
        var text = await reader.ReadToEndAsync();

        return Results.Ok(text);
    });


で、これをテスト. 👇

await using var application = new Application();
using var client = application.CreateClient();

using var formData = new MultipartFormDataContent();
await using var file = File.OpenRead("text.txt");
var streamContent = new StreamContent(file);
formData.Add(streamContent, "file", "text.txt");

var response = await client.PostAsync("/upload",
    formData);

response.StatusCode.Should().Be(HttpStatusCode.OK);
var data = await response.Content.ReadAsStringAsync();
data.Should().Be("\"Hello World!\"");


予想される 200 OK ステータス コードは、415 Unsupported Media Type になりました 🤔

それは奇妙でした.最初に考えたのは、そのエンドポイントで受け入れられるコンテンツ タイプを定義していないということでした.

.Accepts<IFormFile>("multipart/form-data");


上記のコードは OpenAPI メタデータを追加するだけのものであると考えて、自分が愚かであることに気付きました. 😅

そしたら、やっと取れました.最小限の API は、コンテンツが JSON であるという前提で属性をバインドしようとします.

それで、私はそれをどのように処理しますか?



引数として HttpRequest リクエストを受け取る必要がありました.

次に、フォームを読み取ってファイルを探すことができました.

app.MapPost("/upload",
    async Task<IResult>(HttpRequest request) =>
    {
        if (!request.HasFormContentType)
            return Results.BadRequest();

        var form = await request.ReadFormAsync();
        var formFile = form.Files["file"];

        if (formFile is null || formFile.Length == 0)
            return Results.BadRequest();

        await using var stream = formFile.OpenReadStream();

        var reader = new StreamReader(stream);
        var text = await reader.ReadToEndAsync();

        return Results.Ok(text);
    });


最終的には、少し余分な労力が必要になりますが、大したことではありません.おそらく将来のバージョンでは、それを達成するための簡単な方法があるかもしれません.

これがお役に立てば幸いです!このようなヒントをさらに得るには、私に従ってください.連絡を取り合いましょう!