ByteArray 到 IFormFile

sky*_*fer 6 c# file-upload asp.net-core

我正在使用 C# 和 Net Core 开发一些 REST API
我的存储库中有一个函数,它接受类型为 的参数IFormFile

public async Task<bool> UploadFile(IFormFile file)
{
    // do some stuff and save the file to azure storage
}
Run Code Online (Sandbox Code Playgroud)

此函数由控制器方法调用,该方法将上传的文件传递给它

public class FileController : Controller
{
    public async Task<IActionResult> UploadDoc(IFormFile file
    {
        // Call the repository function to save the file on azure
        var res = await documentRepository.UploadFile(file);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我有另一个调用外部 API 的函数,该 API 将文件作为字节数组返回。我想使用该repository.UploadFile方法保存这个字节数组,但我无法将字节数组对象转换为IFormFile.
是否可以?

Ahm*_*eed 21

您可以将字节数组转换为 a MemoryStream

var stream = new MemoryStream(byteArray);
Run Code Online (Sandbox Code Playgroud)

..和然后传递到构造函数中的FromFile类:

IFormFile file = new FormFile(stream, 0, byteArray.Length, "name", "fileName");
Run Code Online (Sandbox Code Playgroud)


小智 7

  1. 基于字节数组创建一个新的MemoryStream。
  2. 基于MemoryStream 创建一个新的FormFile 对象。
  3. 确保附加 ContentDisposition 标头,否则您将无法操作 FormFile 对象,因为将抛出 C# 异常。

完整代码:

        using (var stream = new MemoryStream(byteArray))
        {
            var file = new FormFile(stream, 0, byteArray.Length, name, fileName)
            {
                Headers = new HeaderDictionary(),
                ContentType = contentType,
            };

            System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
            {
                FileName = file.FileName
            };
            file.ContentDisposition = cd.ToString();
        }
Run Code Online (Sandbox Code Playgroud)

  • 这仅适用于控制器吗?我试图在类库中执行此操作,无论我安装什么 NuGet 包,FormFile 都不是程序集的一部分。我尝试过 Microsoft.AspNetCore.Http.FormFile 和 Microsoft.AspNetCore.Http.Internal.FormFile。我目前仍在使用 .Net Core 3.1。 (2认同)

Chr*_*att 5

您的回购不应该使用IFormFile. 这是一种抽象,仅适用于一种特定的 HTTP 文件传输方法(即multipart/form-data编码的请求正文)。像你的 repo 这样的东西应该不知道文件的来源 (HTTP),也不知道它是如何传输的 ( multipart/form-datavsapplication/json例如)。

相反,你应该使用Stream你的参数。UploadDoc那么,在您的行动中,您可以简单地执行以下操作:

using (var stream = file.OpenReadStream())
{
    await documentRepository.UploadFile(stream);
}
Run Code Online (Sandbox Code Playgroud)

而且,您只有一个字节数组:

using (var stream = new MemoryStream(byteArray))
{
    await documentRepository.UploadFile(stream);
}
Run Code Online (Sandbox Code Playgroud)

您还可以考虑添加一个UploadFile需要 a的重载byte[],因为从字节数组创建一个新的内存流只是为了拥有一个流是一种资源浪费。但是, a 的byte[]处理方式必须与 a 不同Stream,因此可能需要一些重复的逻辑才能走这条路线。您需要评估权衡。