在 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

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

相关推荐
我登哥MVP几秒前
Spring Boot 从“会用”到“精通”:SpringBoot MVC 请求处理全流程
java·spring boot·后端·spring·mvc·maven·intellij-idea
我登哥MVP10 分钟前
Spring Boot 从“会用”到“精通”:ReturnValueHandler原理
java·spring boot·后端·spring·java-ee·maven·intellij-idea
伊布拉西莫20 分钟前
Flask 请求生命周期
后端·python·flask
英豪16323 分钟前
@Target + @Retention + isAnnotationPresent + getAnnotation
后端
黄同学real27 分钟前
HJL WebAPI 项目日志入库实战:从建表到自动清理
后端
孟陬28 分钟前
国外技术周刊 #140:在 Jeff Bezos 的私密 Campfire 峰会上,我学到了关于亿万富翁的事
前端·后端
小闹54939 分钟前
CLAUDE CODE生成可视化数据库工具
后端
星星电灯猴1 小时前
全面解决Charles抓取HTTPS请求响应中文乱码问题的方法与技巧
后端·ios