在 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") **如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。**

相关推荐
bcbnb35 分钟前
iOS App混淆实战案例:如何用多工具组合提高App安全性
后端
柠檬树上柠檬果37 分钟前
回溯算法总结
后端
真夜40 分钟前
个人spring-boot问题记录
java·后端
程序员小奕42 分钟前
springboot 百货中心供应链管理系统小程序
java·spring boot·后端
刘白Live1 小时前
【Java】为什么有时候执行countDownLatch+线程池查询列表会丢失数据?
java·后端
梁凌锐1 小时前
重构手法——代码健壮性增强类 | 防御性编程 | 引入特殊情况类
后端
蒋蜀黍2 小时前
Go + open ai 实现一个 mini manus
后端
及丫丫2 小时前
SpringBoot集成MQTT客户端
后端
用户28988180666422 小时前
Sarama消费组初始化阻塞问题排查
后端·go
Java中文社群2 小时前
超实用!手把手教你Dify版本升级
人工智能·后端