c# [FromForm] List<IFormFile> 始终导致 null

问题描述 投票:0回答:1

我想测试用 C# (.NET 8.0) 编写的 REST API 端点。

端点

/import
应从
TestFiles
文件夹中获取多个文件:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapPost("/import", Import).DisableAntiforgery();

static async Task<IResult> Import([FromForm] List<IFormFile> xyz)
{
    if (xyz == null || xyz.Count == 0)
    {
        return Results.BadRequest("No files were provided.");
    }

    // This is never reached !!!

    return Results.Ok();
}

app.Run();

测试看起来像这样:

using Microsoft.AspNetCore.Mvc.Testing;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;

namespace Importer.Tests
{
    public class IntegrationTests(WebApplicationFactory<Program> factory) : IClassFixture<WebApplicationFactory<Program>>
    {
        private readonly WebApplicationFactory<Program> _factory = factory;
        private readonly string _testFilesPath = Path.Combine(Environment.CurrentDirectory, "TestFiles");

        private MultipartFormDataContent CreateMultipartFormDataFromTestFiles(List<string> fileNames)
        {
            var formContent = new MultipartFormDataContent();

            foreach (var fileName in fileNames)
            {
                string filepath = Path.Combine(_testFilesPath, fileName);
                var fileBytes = File.ReadAllBytes(filepath);
                var fileContent = new ByteArrayContent(fileBytes);
                fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
                formContent.Add(fileContent, "xyz", fileName);
                // "files" parameter name should be the same as the server side input parameter name
                //https://learn.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-8.0#match-name-attribute-value-to-parameter-name-of-post-method
            }

            return formContent;
        }

        [Fact]
        public async Task API_Import_File_Should_Return_Http_Status_OK()
        {
            List<string> fileList = new List<string> { "Input.txt" };
            var form = CreateMultipartFormDataFromTestFiles(fileList);

            using var client = _factory.CreateClient();
            var response = await client.PostAsync("/import", form);

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        }
    }
}

问题是列表“xyz”始终为空!

如果删除

[FromForm]
标签,则响应为:

状态代码:415,原因短语:“不支持的媒体类型”

如果端点

/import
更改为仅处理一个文件 =>
IFormFile
,一切正常!

如有任何建议,我们将不胜感激。谢谢

c# rest asp.net-core-mvc http-headers multipartform-data
1个回答
0
投票

在最小 API 中,文件上传支持使用

IFormCollection
IFormFile
.NET 8
中的 IFormFileCollection。请注意,不是
List<IFormFile>
,因此您需要将代码更改为:

static async Task<IResult> Import([FromForm] IFormFileCollection xyz)
{
    if (xyz == null || xyz.Count == 0)
    {
        return Results.BadRequest("No files were provided.");
    }
    foreach (var file in xyz)
    {
        // ...
    }

    return Results.Ok();
}
© www.soinside.com 2019 - 2024. All rights reserved.