【问题标题】:How do I do file upload using ASP.NET Core 6 minimal api?如何使用 ASP.NET Core 6 minimal api 上传文件?
【发布时间】:2022-12-14 11:38:04
【问题描述】:

我想在 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。

关于在这里做什么的任何想法或想法?

【问题讨论】:

    标签: asp.net .net asp.net-core .net-6.0 minimal-apis


    【解决方案1】:

    只是注意这里,你可以上传一个文件任何ContentType 就像下面的示例代码。

    在这个例子中我选择了text/plain ContentType, 但您可以通过将 .Accepts&lt;IFormFile&gt;("text/plain"); 行编辑为您想要的 ContentType 来选择您自己的。

    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 也很好地支持它:

    【讨论】:

    • 如果文件是二进制文件,我认为最好通过request.Form.Files[0] 访问文件而不是从正文中读取。虽然还没有测试过。
    【解决方案2】:

    目前开箱即用的最小 API 绑定支持是 quite limited。支持的绑定源:

    • 路由值
    • 查询字符串
    • 标题
    • 正文(作为 JSON)
    • 依赖注入提供的服务
    • 自定义

    注意:.NET 6 本身不支持从表单绑定

    您可以利用自定义绑定或使用special types handling

    app.MapPost("/upload", (HttpRequest request) =>
    {
        //Do something with the file
        var files = request.Form.Files;
        return Results.Ok();
    })
    .Accepts("multipart/form-data")
    .Produces(200);
    

    【讨论】:

    • 谢谢。明天会考。我只是想知道他们是如何在我提到的博客上做到这一点的?嗯
    • @TomasJansson 我非常确定他们使用的不是最小 API,而是“标准”Web APIs
    • 您是否验证过这确实有效?当我这样做时,我得到一个 Unexpected end of Stream, the content may have already been read by another component. 异常。一个区别是我有 Accepts&lt;IFormFile&gt;("multipart/form-data"),我想这就是为什么 asp.net 尝试读取正文。但我似乎没有非通用的 Accepts 可以使用。
    • 没关系,我认为这是我使用 vs 代码休息客户端创建请求的方式,这就是问题所在,在测试失眠端点时工作正常。
    【解决方案3】:
    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"); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 1970-01-01
      • 1970-01-01
      • 2021-07-07
      相关资源
      最近更新 更多