我想在 ASP.NET Core 6 中创建一个简单的文件上传端点,并认为它会像这里描述的那样简单https://dotnetthoughts.net/handling-file-uploads-in-openapi-with-aspnet-core /.
当我定义了一个端点时:
app.MapPost("/upload", (IFormFile file) =>
{
//Do something with the file
return Results.Ok();
}).Accepts<IFormFile>("multipart/form-data").Produces(200);
我打电话给端点时收到 415 回复。我收到的消息是这样的:
预期支持的 JSON 媒体类型但得到“multipart/form-data; ...
当我说端点应该接受
multipart/form-data
.时,不确定为什么它期望支持的json
关于在这里做什么的任何想法或想法?
目前开箱即用的最小 API 绑定支持相当有限。支持的绑定源:
- 路线价值
- 查询字符串
- 标题
- 正文(作为 JSON)
- 依赖注入提供的服务
- 定制
注意:.NET 6 本身不支持从表单绑定
您可以利用自定义绑定或使用 特殊类型处理:
app.MapPost("/upload", (HttpRequest request) =>
{
//Do something with the file
var files = request.Form.Files;
return Results.Ok();
})
.Accepts("multipart/form-data")
.Produces(200);
更新
IFormFile
/IFormFileCollection
:
app.MapPost("/upload", async (IFormFile file) =>
{
// ...
});
app.MapPost("/upload_many", async (IFormFileCollection myFiles) =>
{
foreach (var file in myFiles)
{
// ...
}
});
这里需要注意的是,您可以像下面的示例代码一样上传具有any ContentType 的文件。
在这个例子中我选择了
ContentType, 但您可以通过将text/plain
行编辑为您想要的 ContentType 来选择您自己的。.Accepts<IFormFile>("text/plain");
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");
Swagger UI也很好的支持:
.NET 7 已解决此问题。添加了对 IFormFile 和 IFormFileCollection 的支持。您应该能够在 MediatR 管道中使用它。
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.MapPost("/upload", async (IFormFile file) =>
{
var tempFile = Path.GetTempFileName();
app.Logger.LogInformation(tempFile);
using var stream = File.OpenWrite(tempFile);
await file.CopyToAsync(stream);
});
app.MapPost("/upload_many", async (IFormFileCollection myFiles) =>
{
foreach (var file in myFiles)
{
var tempFile = Path.GetTempFileName();
app.Logger.LogInformation(tempFile);
using var stream = File.OpenWrite(tempFile);
await file.CopyToAsync(stream);
}
});
app.Run();
app.MapPost("/upload",
async Task<IResult> (HttpRequest request) =>
{
if (!request.HasFormContentType)
return Results.BadRequest();
var form = await request.ReadFormAsync();
if (form.Files.Any() == false)
return Results.BadRequest("There are no files");
var file = form.Files.FirstOrDefault();
if (file is null || file.Length == 0)
return Results.BadRequest("File cannot be empty");
using var stream = file.OpenReadStream();
var reader = new StreamReader(stream);
var text = await reader.ReadToEndAsync();
return Results.Ok(text);
}).Accepts<IFormFile>("multipart/form-data");