在 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

如果您喜歡此文章,請收藏、點贊、評論,謝謝,祝您快樂每一天。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/65398.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/65398.shtml
英文地址,請注明出處:http://en.pswp.cn/web/65398.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue2遷移至rsbuild

背景 由于遠程機器配置較低&#xff0c;每次運行vue2項目都會非常卡。后期項目文件、路由更多的時候&#xff0c;啟動到一半直接會跳出open too many files類似的錯誤&#xff0c;嘗試將路由屏蔽掉只剩下開發所需的一個路由也不行&#xff08;不是說webpack的打包是全部打包&am…

智能手機租賃系統全新模式改變消費習慣與商家盈利路徑

內容概要 智能手機租賃系統的崛起&#xff0c;讓我們瞄到了一個消費市場的新風向標。想象一下&#xff0c;傳統上人們總是為了最新款手機奮不顧身地排隊、借錢甚至是透支信用卡。現在&#xff0c;通過靈活的租賃選項&#xff0c;消費者可以更加隨意地體驗高科技產品&#xff0…

[項目實戰2]貪吃蛇游戲

目錄 貪吃蛇游戲&#xff1a;&#xff1a; 一、游戲效果及功能實現&#xff1a; 1.規則 ??????? ??????? ??????? 2.基本功能實現 ??????? ??????? ??????? 3.技術要點 ???????…

瀏覽器報錯:您的連接不是私密連接,Kubernetes Dashboard無法打開

問題描述 部署完成Kubernetes Dashboard后&#xff0c;打開HTTPS的web頁面&#xff0c;Chrome和Edge瀏覽器都無法正常加載頁面&#xff0c;會提示您的連接不是私密連接的報錯。 ???????????? 原因&#xff1a; 瀏覽器不信任這些自簽名的ssl證書&#xff0c;為了…

關于量子神經網絡的思考

其實在寫這篇文章之前想了很多&#xff0c;主要是想法太超前&#xff0c;有可能顛覆未來機器智能行業甚至是影響世界。 1、計算機的歷史 計算機的歷史可以追溯到20世紀中葉&#xff0c;最早的電子計算機如ENIAC和EDVAC采用了馮諾依曼架構&#xff08;John von Neumann Archit…

docker pull(拉取鏡像)的時候,無法下載或者卡在Waiting的解決方法

docker pull的時候&#xff0c;卡在Waiting的解決方法 一般情況&#xff08;大部分鏡像都可以拉取&#xff09;更換鏡像源 進一步&#xff08;如es等拉取不到&#xff09;在鏡像同步站搜索詳細步驟 還可以在掛載的時候&#xff0c;讓其下載對應的版本 一般情況&#xff08;大部…

PHP二維數組去除重復值

Date: 2025.01.07 20:45:01 author: lijianzhan PHP二維數組內根據ID或者名稱去除重復值 代碼示例如下&#xff1a; // 假設 data數組如下 $data [[id > 1, name > Type A],[id > 2, name > Type B],[id > 1, name > Type A] // 重復項 ];// 去重方法 $dat…

注冊中心如何選型?Eureka、Zookeeper、Nacos怎么選

這是小卷對分布式系統架構學習的第9篇文章&#xff0c;第8篇時只回答了注冊中心的工作原理的內容&#xff0c;面試官的第二個問題還沒回答&#xff0c;今天再來講講各個注冊中心的原理&#xff0c;以及區別&#xff0c;最后如何進行選型 上一篇文章&#xff1a;如何設計一個注冊…

SQL使用視圖

本文將介紹什么是視圖&#xff0c;它們怎樣工作&#xff0c;何時使用它們。 1. 視圖 視圖是虛擬的表。與包含數據的表不一樣&#xff0c;視圖只包含使用時動態檢索數據的查詢。 說明&#xff1a;SQLite 的視圖 SQLite 僅支持只讀視圖&#xff0c;所以視圖可以創建&#xff…

Three.js - 打開Web 3D世界的大門

文章目錄 前言一、Three.js 的起源與背景二、Three.js 的特點三、Three.js 的核心組件詳解四、實際應用案例結語 前言 Three.js 是一個基于JavaScript的庫&#xff0c;它極大地簡化了使用WebGL創建3D圖形的過程。通過封裝復雜的WebGL API&#xff0c;Three.js為開發者提供了一…

恒壓恒流原邊反饋控制芯片 CRE6289F

CRE6289F 系列產品是一款內置高壓 MOS 功率開關管的高性能多模式原邊控制的開關電源芯片。較少的外圍元器件、較低的系統成本設計出高性能的交直流轉換開關電源。CRE6289F 系列產品提供了極為全面和性能優異的智能化保護功能&#xff0c;包括逐周期過流保護、軟啟動、芯片過溫保…

開源 AI 智能名片 2+1 鏈動模式商城小程序在商業營銷中的心理博弈與策略應用

摘要&#xff1a;在當今競爭激烈的商業環境中&#xff0c;理解消費者心理對營銷成敗起著關鍵作用。本文聚焦于消費者 “占便宜” 心理&#xff0c;深入探討開源 AI 智能名片 21 鏈動模式商城小程序如何利用這一心理&#xff0c;在 “雙十一”“雙十二” 等購物熱潮背景下&#…

01 數據分析介紹及工具準備

數據分析介紹及工具準備 一、工具準備二、下載和使用Anaconda三、jupyter notebook常用快捷鍵 一、工具準備 數據科學庫 NumPy&#xff0c;SciPy&#xff0c;Pandas&#xff0c;Scikit-Learn 數據可視化庫 Matplotlib&#xff0c;Seaborn 編譯器 Jupyter Notebook 數據科…

opencv攝像頭標定程序實現

攝像頭標定是計算機視覺中的一個重要步驟&#xff0c;用于確定攝像頭的內參&#xff08;如焦距、主點、畸變系數等&#xff09;和外參&#xff08;如旋轉矩陣和平移向量&#xff09;。OpenCV 提供了方便的工具來進行攝像頭標定。下面分別給出 C 和 Python 的實現。 1. C 實現…

后端Java開發:第十三天

第十三天&#xff1a;繼承 - 面向對象的核心概念 歡迎來到第十三天的學習&#xff01;今天&#xff0c;我們將深入探討 Java 中的 繼承&#xff08;Inheritance&#xff09;&#xff0c;這是面向對象編程的四大基本特性之一。繼承是指一個類&#xff08;子類&#xff09;通過繼…

java項目之網上租貿系統源碼(springboot+mysql+vue)

風定落花生&#xff0c;歌聲逐流水&#xff0c;大家好我是風歌&#xff0c;混跡在java圈的辛苦碼農。今天要和大家聊的是一款基于springboot的網上租貿系統。項目源碼以及部署相關請聯系風歌&#xff0c;文末附上聯系信息 。 項目簡介&#xff1a; 基于Spring Boot的網上租貿…

協方差矩陣

協方差矩陣是一個對稱矩陣&#xff0c;用來描述多個隨機變量之間的協方差關系。協方差反映了兩個隨機變量如何共同變化的趨勢&#xff0c;協方差矩陣將這種關系擴展到了多維數據。 1. 定義 假設有一個 n 維隨機向量 &#xff0c;協方差矩陣 Σ 定義為&#xff1a; 其中&#…

spring boot controller放到那一層

在 Spring Boot 應用程序中&#xff0c;Controller 層通常被放置在應用程序的 表示層&#xff08;Presentation Layer&#xff09; 或 用戶界面層&#xff08;UI Layer&#xff09; 中。Controller 層的主要職責是處理用戶的 HTTP 請求&#xff0c;并將請求轉發給服務層進行業務…

計算機網絡之---局域網

什么叫局域網 局域網&#xff08;LAN&#xff0c;Local Area Network&#xff09; 是指在一個相對較小的區域內&#xff0c;如家庭、辦公室、學校、企業等&#xff0c;連接多個計算機和設備的網絡。局域網的特點是覆蓋范圍小、傳輸速度快、構建成本較低。 局域網的主要特點&…

Spring Boot + Jasypt 實現application.yml 屬性加密的快速示例

Jasypt(Java Simplified Encryption)是一個專為Java應用程序設計的開源加密庫,旨在簡化加密和解密流程,保護敏感數據如密碼、API密鑰等。 jasypt-spring-boot-starter允許開發者在Spring Boot應用中輕松地實現加密和解密功能。 本篇介紹使用 jasypt-spring-boot-starter 以…