.NET 8中[FromForm] List<IFormFile>始终为Null的问题求助
.NET 8 最小API接收多个IFormFile时参数始终为Null的解决方法
问题场景
我基于.NET 8编写的最小API中,/import端点需要批量接收文件,但参数List<IFormFile> xyz始终返回null。移除[FromForm]标签后会收到415 Unsupported Media Type响应;若将端点改为接收单个IFormFile则完全正常。
后端核心代码:
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."); } // 此处代码从未执行 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); } 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); } } }
解决方法
问题出在测试代码的两个细节错误,修正后即可正常绑定文件列表:
1. 修正文件内容的ContentType
测试代码中将文件ContentType设为multipart/form-data是错误的,这是整个表单的类型,而非单个文件的类型。需改为对应文件的实际类型,或通用二进制类型:
// 原错误代码 // fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data"); // 修改为通用二进制类型(适配所有文件) fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream"); // 若明确文件类型,也可针对性设置,比如文本文件: // fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("text/plain");
2. 确保表单参数名符合列表绑定规则
ASP.NET Core绑定List<IFormFile>时,只需重复使用相同的参数名即可自动识别为列表。测试代码中参数名xyz与后端一致,无需额外修改,但需确保上述ContentType修正完成。
修改后的测试方法完整代码:
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); // 设置正确的文件ContentType fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream"); // 重复使用参数名"xyz",自动绑定为列表 formContent.Add(fileContent, "xyz", fileName); } return formContent; }
完成上述修改后,后端的xyz参数即可正确接收上传的文件列表,测试会返回200 OK响应。
内容的提问来源于stack exchange,提问作者user1911091
相关产品推荐
相关产品推荐

