news 2026/4/18 9:54:50

ASP.NET Core如何优化大文件上传的性能?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ASP.NET Core如何优化大文件上传的性能?

政府招投标项目大文件传输解决方案探索

作为山东济南一家软件公司项目负责人,近期我们正全身心投入一个政府招投标项目。在项目推进过程中,大文件传输需求成为了一大关键挑战,必须找到一套契合项目各方面要求的解决方案。

一、项目需求剖析

(一)文件传输规模与功能

本次项目要求支持 50G 左右的大文件传输,涵盖文件和文件夹的上传与下载功能。尤为关键的是,文件夹传输时需完整保留其层级结构,确保数据的完整性和准确性。

(二)信创国产化适配

由于是政府项目,信息安全至关重要,必须全面支持信创国产化环境。具体包括:

  1. 操作系统:统信 UOS、中标麒麟、银河麒麟。
  2. 浏览器:主流浏览器以及信创国产浏览器,如龙芯浏览器、红莲花浏览器、奇安信安全浏览器。
  3. 数据库:主流的 SQL Server、MySQL、Oracle 以及国产化的达梦、人大金仓。

(三)技术架构与部署

后端采用.NET Core 技术栈,前端基于 vue2 - cli 框架。项目部署于内网环境,需支持私有部署,以保障数据的安全性和隐私性。

(四)授权与成本考量

公司客户主要集中在政府和军工单位,考虑到项目数量众多,每年约 2000 + 个,单套授权方式不仅成本高昂,而且管理繁琐。因此,领导决定采购产品源代码,由公司研发部门自主负责后续开发与维护,同时满足产品部门的自研需求。

二、开源组件调研困境

在项目初期,我们对市场上的开源组件进行了广泛调研,但结果不尽如人意。以百度开源的大文件上传组件 WebUploader 为例,该组件目前已经停止更新,缺乏技术支持。我们曾尝试联系开发人员,但发出的消息一个多月都未得到任何回应。其他开源组件也存在类似问题,没有可靠的技术支持渠道,一旦遇到问题无法及时联系到作者解决,这给项目的顺利推进带来了极大风险,因此我们决定重新寻找更合适的解决方案。

三、解决方案探索与部分代码实现

(一)整体架构设计思路

考虑到项目需求和技术栈,我们计划基于.NET Core 和 vue2 - cli 构建一套自定义的大文件传输解决方案。后端负责文件分片处理、存储管理以及与数据库的交互;前端实现文件分片上传、下载以及进度显示等功能。

(二)后端实现(.NET Core)

1. 文件分片接收与合并
usingMicrosoft.AspNetCore.Mvc;usingSystem.IO;[ApiController][Route("api/[controller]")]publicclassFileUploadController:ControllerBase{privatereadonlystring_uploadFolder="Uploads";publicFileUploadController(){if(!Directory.Exists(_uploadFolder)){Directory.CreateDirectory(_uploadFolder);}}[HttpPost("upload")]publicIActionResultUpload([FromForm]FileUploadModelmodel){stringfilePath=Path.Combine(_uploadFolder,model.FileName);stringtempFilePath=filePath+".tmp";// 如果是第一个分片,创建临时文件;否则追加到临时文件if(model.ChunkIndex==0){using(varfileStream=newFileStream(tempFilePath,FileMode.Create)){fileStream.Write(model.FileData,0,model.FileData.Length);}}else{using(varfileStream=newFileStream(tempFilePath,FileMode.Append)){fileStream.Write(model.FileData,0,model.FileData.Length);}}// 如果是最后一个分片,将临时文件重命名为正式文件if(model.IsLastChunk){System.IO.File.Move(tempFilePath,filePath);returnOk(new{message="File uploaded successfully"});}returnOk(new{message="Chunk uploaded successfully"});}}publicclassFileUploadModel{publicstringFileName{get;set;}publicbyte[]FileData{get;set;}publicintChunkIndex{get;set;}publicboolIsLastChunk{get;set;}}
2. 数据库记录文件信息
usingMicrosoft.EntityFrameworkCore;publicclassFileContext:DbContext{publicDbSetFiles{get;set;}publicFileContext(DbContextOptionsoptions):base(options){}}publicclassFileInfo{publicintId{get;set;}publicstringFileName{get;set;}publicstringFilePath{get;set;}publiclongFileSize{get;set;}// 其他文件相关信息字段}

在项目启动时,根据配置的数据库类型(SQL Server、MySQL、Oracle、达梦、人大金仓),配置相应的数据库连接字符串和 EF Core 提供程序。例如,对于 MySQL 数据库:

// 在 Program.cs 中配置 MySQL 数据库连接varbuilder=WebApplication.CreateBuilder(args);// 添加 MySQL EF Core 提供程序builder.Services.AddDbContext(options=>options.UseMySql(builder.Configuration.GetConnectionString("MySQLConnection"),ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("MySQLConnection"))));

(三)前端实现(vue2 - cli)

1. 文件分片上传组件
export default { data() { return { selectedFiles: [], uploadProgress: 0 }; }, methods: { handleFileChange(event) { this.selectedFiles = Array.from(event.target.files); }, async uploadFiles() { for (const file of this.selectedFiles) { const chunkSize = 5 * 1024 * 1024; // 5MB 分片大小 const totalChunks = Math.ceil(file.size / chunkSize); let uploadedChunks = 0; for (let i = 0; i < totalChunks; i++) { const start = i * chunkSize; const end = Math.min(start + chunkSize, file.size); const chunk = file.slice(start, end); const formData = new FormData(); formData.append('FileName', file.name); formData.append('FileData', chunk); formData.append('ChunkIndex', i); formData.append('IsLastChunk', i === totalChunks - 1); try { await this.$http.post('/api/fileupload/upload', formData, { onUploadProgress: (progressEvent) => { uploadedChunks++; this.uploadProgress = Math.round((uploadedChunks / totalChunks) * 100); } }); } catch (error) { console.error('上传分片失败:', error); break; } } } } } };
2. 文件夹层级结构处理

在前端,当用户选择文件夹上传时,需要通过递归的方式遍历文件夹中的所有文件和子文件夹,并为每个文件生成相对路径,以便在传输到后端后能够恢复文件夹的层级结构。

functiontraverseFolder(entry,relativePath=''){returnnewPromise((resolve,reject)=>{constresults=[];if(entry.isFile){entry.file(file=>{// 这里可以对文件进行一些处理,比如设置文件的相对路径file.relativePath=relativePath+file.name;results.push(file);resolve(results);});}elseif(entry.isDirectory){constdirReader=entry.createReader();dirReader.readEntries(entries=>{constpromises=[];for(constsubEntryofentries){constnewRelativePath=relativePath+entry.name+'/';promises.push(traverseFolder(subEntry,newRelativePath));}Promise.all(promises).then(subResults=>{subResults.forEach(subResult=>{results.push(...subResult);});resolve(results);}).catch(reject);},reject);}});}

handleFileChange方法中调用traverseFolder方法来处理文件夹上传:

handleFileChange(event){constfiles=Array.from(event.target.files);constfolderPromises=[];for(constfileoffiles){if(file.webkitRelativePath){// 如果是文件夹中的文件,通过 webkitRelativePath 获取相对路径信息// 这里可以进一步优化处理文件夹层级结构的逻辑constentry={isFile:true,file:(callback)=>{callback(file);}};// 简单模拟,实际需要根据 webkitRelativePath 构建更完整的层级结构处理file.relativePath=file.webkitRelativePath;}else{// 如果是单独的文件,直接处理continue;}}// 更完整的文件夹处理示例if(files.length>0&&files[0].webkitGetAsEntry){constentry=files[0].webkitGetAsEntry();if(entry&&entry.isDirectory){traverseFolder(entry).then(folderFiles=>{this.selectedFiles=this.selectedFiles.concat(folderFiles);});}}},

四、后续计划与展望

目前,我们已经完成了大文件传输解决方案的基本架构设计和部分代码实现。接下来,我们将重点进行以下工作:

  1. 全面测试:在不同信创国产化操作系统和浏览器上进行全面测试,确保文件传输功能的稳定性和兼容性。
  2. 性能优化:对大文件传输过程进行性能优化,提高传输速度和效率,减少传输时间。
  3. 安全加固:加强信息安全防护,对文件传输过程进行加密处理,防止数据泄露。
  4. 完善功能:根据项目实际需求,进一步完善文件夹层级结构处理、文件管理等功能。

通过本次探索和实现,我们有信心为政府招投标项目提供一套满足各方面要求的大文件传输解决方案,为公司赢得更多项目机会,同时也为信创国产化在软件领域的应用贡献一份力量。

设置框架

安装.NET Framework 4.7.2
https://dotnet.microsoft.com/en-us/download/dotnet-framework/net472
框架选择4.7.2

添加3rd引用

编译项目

NOSQL

NOSQL无需任何配置可直接访问页面进行测试

SQL

使用IIS
大文件上传测试推荐使用IIS以获取更高性能。

使用IIS Express

小文件上传测试可以使用IIS Express

创建数据库

配置数据库连接信息

检查数据库配置

访问页面进行测试


相关参考:
文件保存位置,

效果预览

文件上传

文件刷新续传

支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传

文件夹上传

支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。

批量下载

支持文件批量下载

下载续传

文件下载支持离线保存进度信息,刷新页面,关闭页面,重启系统均不会丢失进度信息。

文件夹下载

支持下载文件夹,并保留层级结构,不打包,不占用服务器资源。

下载完整示例

下载完整示例

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 5:21:15

Wan2.2-T2V-A14B在智能家居场景模拟中的交互逻辑体现

Wan2.2-T2V-A14B在智能家居场景模拟中的交互逻辑体现 在今天&#xff0c;当一个用户说“我希望早上醒来时窗帘缓缓拉开&#xff0c;音乐轻柔响起”&#xff0c;我们不再需要依赖抽象的状态图或冗长的代码逻辑去验证这个体验是否合理。借助像Wan2.2-T2V-A14B这样的文本到视频生成…

作者头像 李华
网站建设 2026/4/18 7:02:06

深入剖析高并发场景下ZooKeeper服务端Watcher实现原理

文章目录服务端处理Watcher实现&#xff1f;前言第一章&#xff1a;ZooKeeper 是什么&#xff1f;1.1 核心特性1.2 应用场景第二章&#xff1a;Watcher机制概述2.1 什么是 Watcher&#xff1f;2.2 Watcher 的类型2.3 Why Watcher&#xff1f;第三章&#xff1a;服务端处理 Watc…

作者头像 李华
网站建设 2026/4/18 4:54:52

基于Comsol的激光熔覆熔池流动数值模拟探索

基于Comsol软件的激光熔覆熔池流动数值模拟&#xff0c;考虑马兰戈尼对流&#xff0c;表面张力&#xff0c;重力&#xff0c;浮力等熔池驱动力&#xff0c;并且考虑S活性元素&#xff0c;使得表面张力系数在某一温度由正向负的转变&#xff0c;即马兰戈尼对流方向的改变导致表面…

作者头像 李华
网站建设 2026/4/10 6:02:59

2025年零经验开启漏洞赏金狩猎:好奇心和坚持就是你的超能力

&#x1f41e; 如何在2025年开始漏洞赏金&#xff08;零经验&#xff1f;没问题&#xff09; Abhijeet Kumawat 4 分钟阅读 2025年4月22日 6426 次阅读 ✅免费文章链接“开始漏洞赏金&#xff0c;你不需要成为专业黑客——你只需要好奇心、谷歌搜索和胆量。” 由 Copilot 生成…

作者头像 李华
网站建设 2026/4/18 7:00:13

2000-2023年《中国港口年鉴》

资源介绍 今日数据&#xff1a;更新&#xff01;《中国港口年鉴》2000-2023 一、数据介绍 1、《中国港口年鉴》全面准确地记述和反映了中国大陆江、海、河港口在深化改革、调整结构、整合资源、开拓经营、加快建设等方面所取得的成就和发展进程,本书中凡涉及全国港口资料,一般…

作者头像 李华
网站建设 2026/4/10 22:24:17

Wan2.2-T2V-A14B在环保公益广告创作中的社会责任体现

Wan2.2-T2V-A14B在环保公益广告创作中的社会责任体现技术前沿与社会使命的交汇点 &#x1f30d; 你有没有想过&#xff0c;一条让人泪目的环保短片&#xff0c;可能根本没用摄像机拍摄&#xff1f; 一只在融化的冰川上踽踽独行的北极熊&#xff0c;一片被塑料吞噬的蔚蓝海洋——…

作者头像 李华