在 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<IActionResult> UploadFile(FromFormList<IFormFile> files){...}

但是对于 Net Core 3.1,您将无法从请求中绑定模型 IFormFile(这意味着列表:files.Count 始终返回零):

绑定失败

正确的方法是:

HttpPost("upload")public IActionResult UploadFile(FromForm(Name = "" List<IFormFile> files, string subDirectory){...}

参考链接:File uploads in ASP.NET Core

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

相关推荐
考虑考虑1 小时前
docker compose V2版本新属性
运维·后端·自动化运维
GreenTea3 小时前
7000 万 QPS、500 PB:OpenAI 如何用一个 Python 存储平台撑住 10 亿用户
后端·架构
Flynt3 小时前
Java 27 升级实测:默认值动得比新特性多,有个老参数会让 JVM 直接起不来
java·jvm·后端
Bs_MoneyMagnet3 小时前
基于springboot+vue的个人健康管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·vue3·springboot3·计算机毕业设计
GreenTea4 小时前
OpenAI Agents API 上手实测:一次调用把整个 agent loop 甩给 OpenAI
前端·后端·算法
Bs_MoneyMagnet6 小时前
基于springboot+vue的心理咨询预约与随访平台的设计与实现 源码+文档
vue.js·spring boot·后端·spring·毕业设计·旅游·计算机毕业设计
IT_陈寒7 小时前
Vue的响应式更新把我坑惨了,原来问题出在这
前端·人工智能·后端
陌シ未央ゞ7 小时前
基于BM25算法和RRF实现的混合索引(java版)
人工智能·spring boot·后端·算法
第五页的你8 小时前
SpringBoot基础设施配置(Redis序列化,JJWT新版)
后端
吃饱了得干活8 小时前
RabbitMQ 原理解析(下):存储、集群与可靠投递
后端·rabbitmq