You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET Core中实现此类文件上传?含大文件分块上传适配

在ASP.NET Core中实现文件上传(含大文件分块上传方案)

嘿,我来帮你搞定从.NET Framework迁移到ASP.NET Core的文件上传问题,顺带分享大文件分块上传的实现思路!

一、基础文件上传的正确写法

你之前用的.NET Framework里的Request.Files,在ASP.NET Core中确实要换成Request.Form.Files,但写法上可以更简洁规范,我给你整理两种常用的正确实现:

1. 直接读取Request.Form.Files

如果习惯手动读取请求中的文件,代码可以这么写:

[HttpPost("basic-upload")]
public IActionResult BasicFileUpload()
{
    var uploadedFiles = Request.Form.Files;
    
    foreach (var file in uploadedFiles)
    {
        // 跳过空文件
        if (file.Length == 0) continue;
        
        // 处理文件:比如保存到服务器指定目录
        var safeFileName = Path.GetFileName(file.FileName);
        var savePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/uploads", safeFileName);
        
        using (var fileStream = new FileStream(savePath, FileMode.Create))
        {
            file.CopyTo(fileStream);
        }
    }
    
    return Ok("文件上传完成");
}

2. 参数绑定(更推荐)

ASP.NET Core支持直接将上传文件绑定到IFormFile或List<IFormFile>参数,代码更清晰易读:

[HttpPost("bind-upload")]
public IActionResult BindFileUpload(List<IFormFile> files)
{
    if (files == null || files.Count == 0)
    {
        return BadRequest("未选择任何上传文件");
    }
    
    foreach (var file in files)
    {
        if (file.Length == 0) continue;
        
        // 保存逻辑和上面一致
        var safeFileName = Path.GetFileName(file.FileName);
        var savePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/uploads", safeFileName);
        
        using (var fileStream = new FileStream(savePath, FileMode.Create))
        {
            file.CopyTo(fileStream);
        }
    }
    
    return Ok("文件上传完成");
}

二、大文件分块上传的实现方案

既然你在学习分块上传大文件,我给你梳理ASP.NET Core里的核心实现思路和代码:

分块上传的核心逻辑是:前端把大文件拆分成多个小文件块,分批上传到后端;后端接收每一块并临时存储,等所有块上传完成后,再合并成完整文件。

后端分块上传接口示例

[HttpPost("chunk-upload")]
public async Task<IActionResult> UploadChunk(
    [FromForm] IFormFile chunk,
    [FromForm] int chunkIndex, // 当前块的索引(从0开始)
    [FromForm] int totalChunks, // 文件总块数
    [FromForm] string fileUniqueId) // 文件唯一标识(前端生成,比如GUID或文件哈希)
{
    if (chunk == null || chunk.Length == 0)
    {
        return BadRequest("当前上传块为空");
    }
    
    // 创建临时存储目录(按文件唯一标识分目录,避免冲突)
    var tempDir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/temp-chunks", fileUniqueId);
    Directory.CreateDirectory(tempDir);
    
    // 保存当前块到临时目录
    var chunkSavePath = Path.Combine(tempDir, $"chunk-{chunkIndex}");
    using (var chunkStream = new FileStream(chunkSavePath, FileMode.Create))
    {
        await chunk.CopyToAsync(chunkStream);
    }
    
    // 检查是否所有块都已上传
    var allChunksUploaded = Enumerable.Range(0, totalChunks)
        .All(index => System.IO.File.Exists(Path.Combine(tempDir, $"chunk-{index}")));
    
    if (allChunksUploaded)
    {
        // 合并所有块为完整文件
        var finalFileName = $"merged-{fileUniqueId}{Path.GetExtension(chunk.FileName)}";
        var finalSavePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/uploads", finalFileName);
        
        using (var finalStream = new FileStream(finalSavePath, FileMode.Create))
        {
            for (int i = 0; i < totalChunks; i++)
            {
                var chunkFilePath = Path.Combine(tempDir, $"chunk-{i}");
                using (var chunkStream = new FileStream(chunkFilePath, FileMode.Open))
                {
                    await chunkStream.CopyToAsync(finalStream);
                }
                // 删除临时块文件
                System.IO.File.Delete(chunkFilePath);
            }
        }
        
        // 删除临时目录
        Directory.Delete(tempDir);
        
        return Ok(new { Message = "文件上传并合并完成", FileName = finalFileName });
    }
    
    // 返回当前块上传成功状态,等待其余块
    return Ok(new { Message = $"第{chunkIndex + 1}块上传成功,共{totalChunks}块" });
}

额外注意事项

  • 前端需要确保块的上传顺序正确,并且传递准确的chunkIndex和totalChunks参数
  • 可以添加块校验逻辑,比如前端计算每块的哈希值,后端校验后再保存,避免块损坏
  • 如需断点续传,后端可以记录已上传的块索引,前端上传前先查询已上传的块,跳过重复上传

内容的提问来源于stack exchange,提问作者ProfK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:31:14