在 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([FromForm]List<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

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

相关推荐
Java极客1 小时前
DeepSeek访问卡顿?腾讯云接入让服务更稳定!
后端
来恩10032 小时前
C# ASP.NET 介绍
开发语言·c#·asp.net
韦慕霖2 小时前
C#语言的云计算
开发语言·后端·golang
文军的烹饪实验室2 小时前
使用 Flask 构建流式返回服务
后端·python·flask
全栈Blue3 小时前
记录一次报错:spring security 403报错
java·后端·spring
m0_748230943 小时前
Spring Boot框架知识总结(超详细)
java·spring boot·后端
枣把儿4 小时前
一行 URL 动态生成生成封面,免费、开源、高效
前端·后端·node.js
浮尘笔记5 小时前
go语言简单快速的按顺序遍历kv结构(map)
开发语言·后端·golang
老大白菜5 小时前
使用 Go 语言调用 SiliconFlow 语音生成 API 的脚本,用于将文本转换为 MP3 格式的语音文件。
开发语言·后端·golang
2301_793069825 小时前
前后端分离的网页游戏,后端spring boot,前端vite+vue
前端·后端·vue·springboot·全栈