在 ASP.NET CORE 中上传、下载文件

创建 Web API 来提供跨客户端和服务器的文件上传和下载是常有的事。本文将介绍如何通过 ASP.NET CORE 来实现。

首先在 Visual Studio 中创建空的 Web API 项目,然后选择目标框架 .Net Core 3.1。

创建名为 FileController 的控制器,提供操作文件的接口。

namespace FileAPI.Controllers

{

//[ApiController]

Route("api/\[controller\]")

public class FileController : ControllerBase

{

private readonly FileService _fileService;

public FileController(FileService fileService)

{

_fileService = fileService;

}

// download file(s) to client according path: rootDirectory/subDirectory with single zip file

HttpGet("Download/{subDirectory}")

public IActionResult DownloadFiles(string subDirectory)

{

try

{

var (fileType, archiveData, archiveName) = _fileService.FetechFiles(subDirectory);

return File(archiveData, fileType, archiveName);

}

catch (Exception exception)

{

return BadRequest($"Error: {exception.Message}");

}

}

// upload file(s) to server that palce under path: rootDirectory/subDirectory

HttpPost("upload")

public IActionResult UploadFile([FromForm(Name = "files")] List<IFormFile> files, string subDirectory)

{

try

{

_fileService.SaveFile(files, subDirectory);

return Ok(new { files.Count, Size = FileService.SizeConverter(files.Sum(f => f.Length)) });

}

catch (Exception exception)

{

return BadRequest($"Error: {exception.Message}");

}

}

}

}

创建服务层来实现文件传输的细节。

namespace FileAPI.Services

{

public class FileService

{

public void SaveFile(List<IFormFile> files, string subDirectory)

{

subDirectory = subDirectory ?? string.Empty;

var target = Path.Combine("D:\\webroot\\", subDirectory);

Directory.CreateDirectory(target);

files.ForEach(async file =>

{

if (file.Length <= 0) return;

var filePath = Path.Combine(target, file.FileName);

using (var stream = new FileStream(filePath, FileMode.Create))

{

await file.CopyToAsync(stream);

}

});

}

public (string fileType, byte[] archiveData, string archiveName) FetechFiles(string subDirectory)

{

var zipName = $"archive-{DateTime.Now.ToString("yyyy_MM_dd-HH_mm_ss")}.zip";

var files = Directory.GetFiles(Path.Combine("D:\\webroot\\", subDirectory)).ToList();

using (var memoryStream = new MemoryStream())

{

using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))

{

files.ForEach(file =>

{

var theFile = archive.CreateEntry(file);

using (var streamWriter = new StreamWriter(theFile.Open()))

{

streamWriter.Write(File.ReadAllText(file));

}

});

}

return ("application/zip", memoryStream.ToArray(), zipName);

}

}

public static string SizeConverter(long bytes)

{

var fileSize = new decimal(bytes);

var kilobyte = new decimal(1024);

var megabyte = new decimal(1024 * 1024);

var gigabyte = new decimal(1024 * 1024 * 1024);

switch (fileSize)

{

case var _ when fileSize < kilobyte:

return $"Less then 1KB";

case var _ when fileSize < megabyte:

return $"{Math.Round(fileSize / kilobyte, 0, MidpointRounding.AwayFromZero):##,###.##}KB";

case var _ when fileSize < gigabyte:

return $"{Math.Round(fileSize / megabyte, 2, MidpointRounding.AwayFromZero):##,###.##}MB";

case var _ when fileSize >= gigabyte:

return $"{Math.Round(fileSize / gigabyte, 2, MidpointRounding.AwayFromZero):##,###.##}GB";

default:

return "n/a";

}

}

}

}

现在一切都准备就绪,让我们启动我们的 Web API 应用程序并通过在Postman中填写一些请求来完成测试步骤。

测试下载接口,首先我们建立我们的根目录:"D:\webroot\" 和子目录:"report",然后在里面放一些文件。

文件夹下的文件:D:\webroot\report\

在 Postman 下发起请求:

测试下载接口

  1. 命名请求名称。

  2. 使用GET方法填写相应的 URL。

3 ) 触发请求并检查响应。

测试上传接口,在Postman上发起请求:

1)命名请求名称。

2)使用POST方法填写相应的 URL 。

在 <Body> 标签上:选择表单数据

1、KEY:文件(类型选择文件),VALUE:选择您想要的任何文件。

2、KEY:子目录,VALUE:目标文件夹。 ✨您可以根据需要上传单个文件或多个文件。 ✨KEY 的属性名称映射到 WEB API 参数的名称。

3)发出请求并检查响应。

如果您想将您的 Web API 从 .Net Core 2.2 移植到 3.1,您需要注意一些事情

如果您的客户端的数据表单(网页)没有给出特定名称,则以下示例在 Web API .Net Core 2.2 下运行。

例如:

<form method="post" enctype="multipart/form-data" action="/api/upload">

<input type="file" name="" multiple />

<br />

<input type="submit" value="submit" />

</form>

HttpPost("upload")\]public async Task\ UploadFile(\[FromForm\]List\ files){...} 但是对于 Net Core 3.1,您将无法从请求中绑定模型 IFormFile(这意味着列表:files.Count 始终返回零): ![](https://i-blog.csdnimg.cn/direct/b99f2188af3d4e9c9287db71d62ebca6.png) 绑定失败 正确的方法是: \[HttpPost("upload")\]public IActionResult UploadFile(\[FromForm(Name = ""\] List\ files, string subDirectory){...} 参考链接:[File uploads in ASP.NET Core](https://gunnarpeipman.com/aspnet-core-file-uploads/ "File uploads in ASP.NET Core") **如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。**

相关推荐
喵手10 分钟前
如何利用Java的Stream API提高代码的简洁度和效率?
java·后端·java ee
掘金码甲哥16 分钟前
全网最全的跨域资源共享CORS方案分析
后端
m0_4805026423 分钟前
Rust 入门 生命周期-next2 (十九)
开发语言·后端·rust
张醒言30 分钟前
Protocol Buffers 中 optional 关键字的发展史
后端·rpc·protobuf
鹿鹿的布丁1 小时前
通过Lua脚本多个网关循环外呼
后端
墨子白1 小时前
application.yml 文件必须配置哇
后端
xcya1 小时前
Java ReentrantLock 核心用法
后端
用户466537015051 小时前
如何在 IntelliJ IDEA 中可视化压缩提交到生产分支
后端·github
小楓12011 小时前
MySQL數據庫開發教學(一) 基本架構
数据库·后端·mysql
天天摸鱼的java工程师1 小时前
Java 解析 JSON 文件:八年老开发的实战总结(从业务到代码)
java·后端·面试