news 2026/5/12 9:52:45

ASP.NET WebForm中如何实现分片上传大文件并支持断点续传?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ASP.NET WebForm中如何实现分片上传大文件并支持断点续传?

咱上海.NET程序员实锤了!最近接了个外包活,客户是做企业资料管理的,非要搞个大文件上传下载功能——要求20G文件随便传,文件夹保留层级(比如/部门/2024项目/设计稿/初稿.psd这种),还要兼容IE8(客户那帮老机器还在Win7+IE8上跑,删不得碰不得)。网上翻了一圈代码,不是只有文件上传,就是文件夹层级丢了,要么断点续传一重启就废……今天必须把这需求啃下来,顺便给兄弟们交个底!


需求拆解:我要的到底是个啥?

简单说就仨核心:

  1. 大文件+文件夹:20G文件分片传,文件夹保留层级(1000个子文件也不乱)。
  2. 兼容老古董:IE8用Flash,其他浏览器用H5,Win7+IE9也能跑。
  3. 加密+断点:传输用AES/SM4,存储加密,断点进度存本地(关浏览器也不丢)。
  4. 下载不打包:几万个文件批量下,别让用户等压缩包解压(直接流式下)。

前端:Vue3 + WebUploader(兼容IE8的救命稻草)

IE8不支持H5的File API,只能靠Flash补全。WebUploader是百度开源的,支持Flash/H5双模式,正好适配老浏览器。前端核心逻辑:分片上传、断点查询、文件夹遍历、加密预处理。

1. 前端关键代码(Vue3组件)
import SparkMD5 from 'spark-md5'; // 计算文件MD5(断点续传关键) import WebUploader from 'webuploader'; // 引入WebUploader库 import CryptoJS from 'crypto-js'; // AES加密库(传输加密) export default { data() { return { uploader: null, // WebUploader实例 progress: 0, // 上传进度百分比 isUploading: false, // 是否正在上传 currentFile: null, // 当前处理的文件 fileMd5: '', // 当前文件的MD5(唯一标识,用于断点) chunkSize: 2 * 1024 * 1024, // 分片大小2MB(20G分10000片) uploadedChunks: [], // 已上传的分片序号(从本地localStorage读) encryptKey: 'user-defined-sm4-key-123' // 加密密钥(实际项目要让用户输入!) }; }, mounted() { this.initUploader(); // 初始化上传组件 }, methods: { // 清空队列 clearQueue() { this.uploader.clearQueue(); this.progress = 0; this.currentFile = null; this.uploadedChunks = []; } } };

后端:ASP.NET C# WebForm(兼容老技术的救星)

客户要求用ASP.NET WebForm,虽然新项目很少用,但老系统维护方便。后端核心逻辑:接收分片、记录进度、合并文件、加密存储。

1. 数据库设计(SQL Server)

需要两张表:FileRecord(文件元信息)和FileChunk(分片记录)。

-- 文件元信息表CREATETABLEdbo.FileRecord(Id UNIQUEIDENTIFIERPRIMARYKEYDEFAULTNEWID(),-- 主键FileName NVARCHAR(255)NOTNULL,-- 文件名(含路径,如"部门/2024项目/数据.xlsx")FilePath NVARCHAR(500)NOTNULL,-- 服务器存储路径(如"E:/uploads/")FileSizeBIGINTNOTNULL,-- 文件大小(字节)Md5 NVARCHAR(32)NOTNULL,-- 文件MD5(唯一标识)EncryptKey NVARCHAR(255)NOTNULL,-- 加密密钥(AES密钥)CreateTimeDATETIMEDEFAULTGETDATE()-- 创建时间);-- 文件分片记录表CREATETABLEdbo.FileChunk(Id UNIQUEIDENTIFIERPRIMARYKEYDEFAULTNEWID(),FileMd5 NVARCHAR(32)NOTNULL,-- 关联FileRecord.Md5ChunkNumberINTNOTNULL,-- 分片序号(0开始)ChunkPath NVARCHAR(500)NOTNULL,-- 分片临时存储路径IsUploadedBITDEFAULT0,-- 是否已上传(0未上传,1已上传)CreateTimeDATETIMEDEFAULTGETDATE(),UNIQUENONCLUSTERED(FileMd5,ChunkNumber)-- 防止重复分片);
2. 后端关键接口(ASP.NET WebForm)
// UploadHandler.ashx(处理分片上传)publicclassUploadHandler:IHttpHandler,IRequiresSessionState{privatestring_uploadDir=HttpContext.Current.Server.MapPath("~/Uploads/Temp/");// 临时分片存储路径privatestring_encryptKey="user-defined-sm4-key-123";// 实际从请求参数获取publicvoidProcessRequest(HttpContextcontext){context.Response.ContentType="application/json";stringaction=context.Request["action"];switch(action){case"init":// 初始化上传(生成MD5并查询已上传分片)InitUpload(context);break;case"chunk":// 接收分片上传UploadChunk(context);break;case"merge":// 合并分片MergeChunks(context);break;default:context.Response.Write(JsonConvert.SerializeObject(new{code=400,msg="无效操作"}));break;}}// AES加密工具方法(与前端对应)privatebyte[]AesEncrypt(byte[]data,intoffset,intlength,stringkey){using(Aesaes=Aes.Create()){aes.Key=Encoding.UTF8.GetBytes(key);aes.Mode=CipherMode.ECB;aes.Padding=PaddingMode.PKCS7;ICryptoTransformencryptor=aes.CreateEncryptor(aes.Key,aes.IV);returnencryptor.TransformFinalBlock(data,offset,length);}}// AES解密工具方法(与前端对应)privatebyte[]AesDecrypt(byte[]data,stringkey){using(Aesaes=Aes.Create()){aes.Key=Encoding.UTF8.GetBytes(key);aes.Mode=CipherMode.ECB;aes.Padding=PaddingMode.PKCS7;ICryptoTransformdecryptor=aes.CreateDecryptor(aes.Key,aes.IV);returndecryptor.TransformFinalBlock(data,0,data.Length);}}publicboolIsReusable=>false;}
3. 下载功能(非打包方式)

用户要下载几万个文件,直接打包会炸内存。用FileStreamResult流式输出,逐个读取文件并写入响应流。

// DownloadHandler.ashx(处理文件夹下载)publicclassDownloadHandler:IHttpHandler{publicvoidProcessRequest(HttpContextcontext){stringfolderPath=context.Request["folderPath"];// 前端传的文件夹路径(如"/部门/2024项目/")stringserverPath=HttpContext.Current.Server.MapPath($"~/Uploads/{folderPath}");if(!Directory.Exists(serverPath)){context.Response.StatusCode=404;context.Response.End();return;}// 获取文件夹下所有文件(递归遍历子目录)varfiles=Directory.GetFiles(serverPath,"*.*",SearchOption.AllDirectories);context.Response.ContentType="application/octet-stream";context.Response.Headers.Add("Content-Disposition",$"attachment; filename={HttpUtility.UrlEncode(folderPath)}");foreach(varfileinfiles){stringrelativePath=Path.GetRelativePath(serverPath,file);context.Response.Headers.Add($"Content-Disposition: file; filename={HttpUtility.UrlEncode(relativePath)}");byte[]buffer=File.ReadAllBytes(file);context.Response.OutputStream.Write(buffer,0,buffer.Length);context.Response.Flush();}context.Response.End();}publicboolIsReusable=>false;}

兼容性兜底方案(IE8/IE9)

  • Flash上传:WebUploader的Flash模式在IE8必须,需确保Uploader.swf路径正确,且浏览器允许Flash运行(学校机房可能需要调整安全设置)。
  • 分片大小:IE8对分片支持一般,建议分片大小设为2MB(太小会增加请求次数,太大容易超时)。
  • 文件夹上传:IE9+支持webkitdirectory属性(WebUploader自动处理),IE8只能手动让用户输入文件夹路径(比如在文件名前加部门/2024项目/前缀),后端按路径创建目录。

部署说明(小白必看)

  1. 环境准备

    • 安装IIS(Windows服务器),启用ASP.NET WebForm支持。
    • 安装SQL Server,创建数据库并执行提供的SQL脚本。
    • 下载WebUploader的Uploader.swf,放在/static/webuploader/目录下。
  2. 配置修改

    • 后端UploadHandler.ashxDownloadHandler.ashx的路径添加到IIS的“处理程序映射”中。
    • 修改_uploadDir_encryptKey为实际值(密钥建议让用户输入,别硬编码)。
  3. 测试步骤

    • 用Win7虚拟机装IE8,测试文件夹上传(上传到50%时关闭浏览器,重新打开继续传)。
    • 用Chrome测试大文件下载(选几万个小文件,看是否流式下载不卡顿)。

求救!群里喊一嗓子

现在代码框架搭好了,但有几个坑还没填:

  • IE8下Flash上传的跨域问题(需在IIS根目录放crossdomain.xml)。
  • 20G文件合并时的内存溢出(可能需要分块读取写入)。
  • 加密密钥的安全存储(用户忘记密钥怎么办?需要设计密钥找回功能)。

群里加了个374992201,新人有红包!求大神来群里指导,或者直接甩个DEMO链接!外包答辩就靠这个了,要是能上线,说不定还能接点私活(群里说推荐项目提20%提成,10万项目提2万,比打工香多了!)

(PS:客户说“能跑起来就行”,但我想做得更完美——毕竟这是吃饭的本事,冲就完事了!)

设置框架

安装.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/5/10 4:45:04

【dz-1141】密码锁

摘要 随着社会安全意识的不断提升,对出入口安全防护的需求日益增长。传统机械锁存在钥匙易丢失、复制难度低、安全性不足等问题,难以满足现代生活和工作对安全防护的高要求。 基于 STC89C52 单片机的密码锁,整合了 44 矩阵键盘、AT24C02 存…

作者头像 李华
网站建设 2026/5/3 12:36:21

《从接口到架构:Python持久内存编程深度指南》

长期深耕数据密集型应用的开发实践,会清晰感知到Python在持久内存领域的进化轨迹—早期它只是底层技术的“上层翻译者”,通过封装接口降低开发者的使用门槛,而随着技术实践的深入,Python凭借自身动态特性与生态优势,逐渐构建起一套独特的“灵活存续”编程逻辑,让持久内存…

作者头像 李华
网站建设 2026/5/2 13:30:46

计算机毕设Java苗木交易互助网站 基于Java的苗木交易互助平台设计与实现 Java技术驱动的苗木交易互助管理系统开发

计算机毕设Java苗木交易互助网站l6l169 (配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。随着信息技术的飞速发展,传统的苗木交易管理方式逐渐暴露出效率低下、信息不透…

作者头像 李华
网站建设 2026/5/3 17:41:26

智能重构新范式:AI如何破解Java遗留系统改造难题

在企业数字化转型进程中,Java遗留系统的现代化改造始终是技术团队面临的重要挑战。传统重构过程中,开发人员需要应对代码结构复杂、文档缺失、技术债务累积等多重障碍,这些因素显著增加了项目风险和开发成本。遗留系统重构的核心挑战技术债务…

作者头像 李华
网站建设 2026/5/10 19:16:33

渲染引擎多线程优化避坑指南(资深架构师亲授10年踩坑经验)

第一章:渲染引擎多线程优化的挑战与现状现代图形应用对实时性和性能的要求日益提升,渲染引擎作为核心组件,其多线程优化成为关键技术瓶颈。随着硬件多核架构的普及,传统单线程渲染模式已无法充分利用计算资源,导致CPU利…

作者头像 李华
网站建设 2026/5/8 12:32:28

【系统级编程必修课】:深入理解内存布局的7个关键维度

第一章:内存布局精确控制在系统级编程中,内存布局的精确控制是优化性能与确保硬件兼容性的关键。尤其是在操作系统开发、嵌入式系统或高性能计算场景中,开发者需要直接干预数据在内存中的排列方式,以满足对齐要求、减少缓存行冲突…

作者头像 李华