原文作者:Jay Krishna Reddy
原文鏈接:https://www.c-sharpcorner.com/article/upload-and-download-multiple-files-using-web-api/
翻譯:沙漠盡頭的狼(谷歌翻譯加持,文中版本使用.NET 6升級)
---正文開始---
今天,我們將通過一個簡單的過程介紹使用 ASP.Net Core 6.0 Web API 上傳和下載多個文件。
步驟
首先在 Visual Studio 中創建一個空的 Web API 項目,目標框架選擇.Net 6.0
。
此項目中沒有使用外部包。
創建一個 Services
文件夾,并在其中創建一個 FileService
類和 IFileService
接口。
我們在這個 FileService.cs
中使用了三個方法
UploadFile
DownloadFile
SizeConverter
由于我們需要一個文件夾來存儲這些上傳文件,因此我們在這里添加了一個參數來將文件夾名稱作為字符串傳遞,它將存儲所有上傳的這些文件。
FileService.cs
using?System.IO.Compression;namespace?FileUploadAndDownload.Services;public?class?FileService?:?IFileService
{#region?Propertyprivate?readonly?IWebHostEnvironment?_webHostEnvironment;#endregion#region?Constructorpublic?FileService(IWebHostEnvironment?webHostEnvironment){_webHostEnvironment?=?webHostEnvironment;}#endregion#region?Upload?Filepublic?void?UploadFile(List<IFormFile>?files,?string?subDirectory){subDirectory?=?subDirectory????string.Empty;var?target?=?Path.Combine(_webHostEnvironment.ContentRootPath,?subDirectory);Directory.CreateDirectory(target);files.ForEach(async?file?=>{if?(file.Length?<=?0)?return;var?filePath?=?Path.Combine(target,?file.FileName);await?using?var?stream?=?new?FileStream(filePath,?FileMode.Create);await?file.CopyToAsync(stream);});}#endregion#region?Download?Filepublic?(string?fileType,?byte[]?archiveData,?string?archiveName)?DownloadFiles(string?subDirectory){var?zipName?=?$"archive-{DateTime.Now:yyyy_MM_dd-HH_mm_ss}.zip";var?files?=?Directory.GetFiles(Path.Combine(_webHostEnvironment.ContentRootPath,?subDirectory)).ToList();using?var?memoryStream?=?new?MemoryStream();using?(var?archive?=?new?ZipArchive(memoryStream,?ZipArchiveMode.Create,?true)){files.ForEach(file?=>{var?theFile?=?archive.CreateEntry(Path.GetFileName(file));using?var?binaryWriter?=?new?BinaryWriter(theFile.Open());binaryWriter.Write(File.ReadAllBytes(file));});}return?("application/zip",?memoryStream.ToArray(),?zipName);}#endregion#region?Size?Converterpublic?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);return?fileSize?switch{_?when?fileSize?<?kilobyte?=>?"Less?then?1KB",_?when?fileSize?<?megabyte?=>$"{Math.Round(fileSize?/?kilobyte,?0,?MidpointRounding.AwayFromZero):##,###.##}KB",_?when?fileSize?<?gigabyte?=>$"{Math.Round(fileSize?/?megabyte,?2,?MidpointRounding.AwayFromZero):##,###.##}MB",_?when?fileSize?>=?gigabyte?=>$"{Math.Round(fileSize?/?gigabyte,?2,?MidpointRounding.AwayFromZero):##,###.##}GB",_?=>?"n/a"};}#endregion
}
SizeConverter
函數用于獲取我們上傳文件到服務器的實際大小。
IFileService.cs
namespace?FileUploadAndDownload.Services;public?interface?IFileService
{void?UploadFile(List<IFormFile>?files,?string?subDirectory);(string?fileType,?byte[]?archiveData,?string?archiveName)?DownloadFiles(string?subDirectory);string?SizeConverter(long?bytes);
}
讓我們在 Program.cs
文件中添加這個服務依賴項
Program.cs
using?FileUploadAndDownload.Services;var?builder?=?WebApplication.CreateBuilder(args);//?Add?services?to?the?container.builder.Services.AddControllers();
//?Learn?more?about?configuring?Swagger/OpenAPI?at?https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();//?主要是添加下面這句代碼,注入文件服務
builder.Services.AddTransient<IFileService,?FileService>();var?app?=?builder.Build();//?Configure?the?HTTP?request?pipeline.
if?(app.Environment.IsDevelopment())
{app.UseSwagger();app.UseSwaggerUI();
}app.UseHttpsRedirection();app.UseAuthorization();app.MapControllers();app.Run();
創建一個 FileController
,并 FileController
中的構造函數注入 IFileService
。
FileController.cs
using?FileUploadAndDownload.Services;
using?Microsoft.AspNetCore.Mvc;
using?System.ComponentModel.DataAnnotations;namespace?FileUploadAndDownload.Controllers;[Route("api/[controller]")]
[ApiController]
public?class?FileController?:?ControllerBase
{private?readonly?IFileService?_fileService;public?FileController(IFileService?fileService){_fileService?=?fileService;}[HttpPost(nameof(Upload))]public?IActionResult?Upload([Required]?List<IFormFile>?formFiles,?[Required]?string?subDirectory){try{_fileService.UploadFile(formFiles,?subDirectory);return?Ok(new?{?formFiles.Count,?Size?=?_fileService.SizeConverter(formFiles.Sum(f?=>?f.Length))?});}catch?(Exception?ex){return?BadRequest(ex.Message);}}[HttpGet(nameof(Download))]public?IActionResult?Download([Required]?string?subDirectory){try{var?(fileType,?archiveData,?archiveName)?=?_fileService.DownloadFiles(subDirectory);return?File(archiveData,?fileType,?archiveName);}catch?(Exception?ex){return?BadRequest(ex.Message);}}
}
我們可以在 swagger
和 postman
中測試我們的 API。

在這里,我們看到了我們創建的用于上傳和下載的兩個 API,因此讓我們分別測試它們中的每一個。

在 subDirectory
字段中 輸入文件保存的文件夾名稱,并在下面添加文件用于保存在服務器對應的子文件夾名稱下。作為響應,我們會看到文件的總數和所有上傳文件的總實際大小。

現在將檢查下載 API。由于我們的文件夾中有多個文件,它將作為Zip
文件下載,我們需要將其解壓縮以檢查文件。

總結
使用Web API接口的方式上傳和下載文件,適用于Blazor Server、Blazor Client、MAUI、Winform、WPF等客戶端程序,后面有空寫寫客戶端怎么調用這些接口。
本文源碼:FileUploadAndDownload[1]
.... 保持學習 !!!
參考資料
[1]
FileUploadAndDownload: https://github.com/dotnet9/ASP.NET-Core-Test/tree/master/src/FileUploadAndDownload