返回

ASP.NET Core实现文件分片上传完整指南(含代码示例)

2026-04-24 ASP.NET Core 文件上传 13 0

在现代Web应用中,大文件上传(如视频、备份文件)已成为常见需求。传统一次性上传不仅容易失败,还会占用大量内存。文件分片上传(Chunk Upload)正是解决这一问题的主流方案。

本文将系统讲解如何在ASP.NET Core中实现文件分片上传,包括原理、实现方式及完整代码示例。

什么是文件分片上传?

文件分片上传是指:将大文件拆分为多个小块(chunk),逐个上传到服务器,最终再进行合并。

其核心优势包括:

  • 提高上传成功率(失败可重试某一块)
  • 支持断点续传
  • 降低服务器内存压力
  • 更适合大文件(如>100MB)

分片上传通常采用多次HTTP请求的方式逐块发送数据 。

ASP.NET Core文件上传机制基础

在ASP.NET Core中,文件上传主要有两种方式:

  1. 缓冲上传(IFormFile):适用于小文件
  2. 流式上传(Stream):适用于大文件

默认情况下,框架对文件大小存在限制(如128MB),并且会进行内存/磁盘缓冲 。

分片上传本质上是:基于流式处理 + 分段控制 + 文件合并。

分片上传整体流程

完整流程如下:

  1. 前端将文件切片(Blob.slice)
  2. 每个分片附带元信息上传:文件名、当前分片索引、总分片数、唯一标识(uploadId)
  3. 后端接收分片并保存
  4. 所有分片上传完成后进行合并
  5. 返回最终结果

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应用,尤其是在云原生和高并发场景下表现更优。

顶部