ASP.NET Core实现文件分片上传完整指南(含代码示例)
2026-04-24 13 0
在现代Web应用中,大文件上传(如视频、备份文件)已成为常见需求。传统一次性上传不仅容易失败,还会占用大量内存。文件分片上传(Chunk Upload)正是解决这一问题的主流方案。
本文将系统讲解如何在ASP.NET Core中实现文件分片上传,包括原理、实现方式及完整代码示例。
什么是文件分片上传?
文件分片上传是指:将大文件拆分为多个小块(chunk),逐个上传到服务器,最终再进行合并。
其核心优势包括:
- 提高上传成功率(失败可重试某一块)
- 支持断点续传
- 降低服务器内存压力
- 更适合大文件(如>100MB)
分片上传通常采用多次HTTP请求的方式逐块发送数据 。
ASP.NET Core文件上传机制基础
在ASP.NET Core中,文件上传主要有两种方式:
- 缓冲上传(IFormFile):适用于小文件
- 流式上传(Stream):适用于大文件
默认情况下,框架对文件大小存在限制(如128MB),并且会进行内存/磁盘缓冲 。
分片上传本质上是:基于流式处理 + 分段控制 + 文件合并。
分片上传整体流程
完整流程如下:
- 前端将文件切片(Blob.slice)
- 每个分片附带元信息上传:文件名、当前分片索引、总分片数、唯一标识(uploadId)
- 后端接收分片并保存
- 所有分片上传完成后进行合并
- 返回最终结果
ASP.NET Core服务端实现
1. 定义分片模型
public class ChunkUploadModel
{
public string FileName { get; set; }
public int ChunkIndex { get; set; }
public int TotalChunks { get; set; }
public string UploadId { get; set; }
}
2. 上传分片接口
[HttpPost("upload-chunk")]
public async Task<IActionResult> UploadChunk(
IFormFile file,
[FromForm] ChunkUploadModel model)
{
var chunkPath = Path.Combine("uploads", model.UploadId);
if (!Directory.Exists(chunkPath))
Directory.CreateDirectory(chunkPath);
var filePath = Path.Combine(chunkPath, $"{model.ChunkIndex}.part");
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
return Ok(new { message = "Chunk uploaded" });
}
3. 合并分片接口
[HttpPost("merge-chunks")]
public IActionResult MergeChunks([FromBody] ChunkUploadModel model)
{
var chunkPath = Path.Combine("uploads", model.UploadId);
var finalPath = Path.Combine("uploads", model.FileName);
using (var output = new FileStream(finalPath, FileMode.Create))
{
for (int i = 0; i < model.TotalChunks; i++)
{
var chunkFile = Path.Combine(chunkPath, $"{i}.part");
using (var input = new FileStream(chunkFile, FileMode.Open))
{
input.CopyTo(output);
}
}
}
Directory.Delete(chunkPath, true);
return Ok(new { message = "File merged successfully" });
}
前端分片上传示例(JavaScript)
async function uploadFile(file) {
const chunkSize = 2 * 1024 * 1024; // 2MB
const totalChunks = Math.ceil(file.size / chunkSize);
const uploadId = Date.now().toString();
for (let i = 0; i < totalChunks; i++) {
const chunk = file.slice(i * chunkSize, (i + 1) * chunkSize);
let formData = new FormData();
formData.append("file", chunk);
formData.append("FileName", file.name);
formData.append("ChunkIndex", i);
formData.append("TotalChunks", totalChunks);
formData.append("UploadId", uploadId);
await fetch("/upload-chunk", {
method: "POST",
body: formData
});
}
await fetch("/merge-chunks", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
fileName: file.name,
totalChunks: totalChunks,
uploadId: uploadId
})
});
}
进阶优化方案
1. 断点续传
- 记录已上传分片(Redis / DB)
- 前端跳过已完成chunk
2. 并发上传
- 使用 Promise.all 并行上传
- 显著提升速度
3. 秒传(去重)
- 计算文件Hash(MD5)
- 服务端判断是否已存在
4. 云存储集成
- Azure Blob / OSS / S3 支持分片上传
- 可直接使用SDK
安全与性能建议
ASP.NET Core官方建议重点关注:
- 限制上传文件大小
- 校验文件类型(防止恶意文件)
- 使用安全文件名
- 存储在非Web目录
- 关闭执行权限
同时建议:
- 使用流式写入(避免内存爆炸)
- 分片大小控制在1MB~5MB之间
- 设置超时与重试机制
总结
文件分片上传是构建大文件上传系统的核心技术。在ASP.NET Core中,可以通过前端切片 + 后端接收,临时存储分片,最终合并文件来实现一个稳定、高性能、可扩展的上传系统。
相比传统上传方式,分片上传更适合现代Web应用,尤其是在云原生和高并发场景下表现更优。