ASPNetCore - 通过 REST 上传文件

Posted

技术标签:

【中文标题】ASPNetCore - 通过 REST 上传文件【英文标题】:ASPNetCore - Uploading a file through REST 【发布时间】:2018-10-17 19:33:18 【问题描述】:

我正在使用 Insomnia 测试 API,但 Postman 也是如此。

我想使用以下控制器测试文件上传:

public async Task<IActionResult> Post([FromForm]IFormFile File)

如果我将请求设置为多部分请求:

它有效。

但是,如果我将其设置为二进制文件:

我不知道如何获取数据。怎么办?

另外,在控制器方法的签名中,如果我将 [FromForm] 更改为 [FromBody],我将无法获取数据。

有人可以帮我澄清一下吗?

【问题讨论】:

您对通过 API 上传文件有任何 API 要求/合同吗? IE。使用表单数据,将文件嵌入正文等。 不,我的意思是它不适用于特定的应用程序:我试图理解为什么我可以将二进制文档作为多部分发送,但不能作为二进制文档发送。这真的是关于了解请求等方面的差异 好的。让我玩这个,我会回复你的。 抱歉耽搁了,只贴了几个例子。 【参考方案1】:

正如您已经注意到的,在 Postman/Insomnia 中使用 binary file 选项并不是标准方式。通过 RESTful API 上传文件有三种不同的方式,您必须选择一种。

我已经包含了代码 sn-ps,它将上传的文件内容读取到一个字符串并输出它——尝试发送一个文本文件,你应该在 200 响应中获得文件的内容。

表单数据上传

这是最流行/知名的上传方法,将您发送的数据格式化为一组键/值对。您通常需要在请求中指定Content-Typemultipart/form-data,然后在MVC 中使用[FromForm] 属性将值绑定到变量。另外,您可以使用内置的IFormFile 类来访问上传的文件。

[HttpPost]
public async Task<IActionResult> PostFormData([FromForm] IFormFile file)

    using (var sr = new StreamReader(file.OpenReadStream()))
    
        var content = await sr.ReadToEndAsync();
        return Ok(content);
    

正文上传

您可以以 MVC 可以理解的格式发送正文,例如JSON,并将文件嵌入其中。通常,文件内容将使用 Base64 或其他编码进行编码,以防止出现字符编码/解码问题,尤其是在您发送图像或二进制数据时。例如


    "file": "MTIz"

然后在你的控制器中指定[FromBody],并使用类进行模型反序列化。

[HttpPost]
public IActionResult PostBody([FromBody] UploadModel uploadModel)

    var bytes = Convert.FromBase64String(uploadModel.File);
    var decodedString = Encoding.UTF8.GetString(bytes);
    return Ok(decodedString);

// ...
public class UploadModel

    public string File  get; set; 

当使用大型非文本文件时,JSON 请求会变得笨重且难以阅读。

二进制文件

这里的关键是您的文件是整个请求。该请求不包含任何其他信息来帮助 MVC 将值绑定到代码中的变量。因此,要访问该文件,需要读取Request中的Body

[HttpPost]
public async Task<IActionResult> PostBinary()

    using (var sr = new StreamReader(Request.Body))
    
        var body = await sr.ReadToEndAsync();
        return Ok(body);
    

注意:该示例将Body 读作string。您可能希望在应用程序中使用Streambyte[] 以避免文件数据编码问题。

【讨论】:

两天,两天我花了...谢谢。 这是黄金!为什么这不在官方 ASP.NETCORE 文档中?! 这很有帮助。您会推荐哪种方法来上传大型二进制文件。第 3 种方法(二进制文件)的文件大小是否受到 maxRequestLength 以外的限制? 你太棒了 我最终使用了 Request.Body.CopyToAsync(memorystream),效果很好。【参考方案2】:

除此之外,多部分文件转base64String的情况可以参考以下:

if (File.Length> 0)
   
       using (var ms = new MemoryStream())
       
           File.CopyTo(ms);
           var fileBytes = ms.ToArray();
           string s = Convert.ToBase64String(fileBytes);                                    
       
    

注意:我将此代码用于 .NET CORE 2.1

【讨论】:

以上是关于ASPNetCore - 通过 REST 上传文件的主要内容,如果未能解决你的问题,请参考以下文章

通过 REST API 上传多部分文件会损坏文件并增加文件大小

Django Rest Framework:通过 AJAX 上传文件

使用 NodeJS REST API 通过 Google Cloud Storage 获取文件上传进度

在 Django 中上传文件,然后通过 REST 将其发送到其他地方? [关闭]

通过Google Drive REST API上传或创建包含内容的新文件?

如何使用 REST API 将文件和附件上传到 sobject 记录?