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

C# .NET 5大视频分块上传服务端获取ByteArrayContent问题咨询

解决方案

问题原因

  • 异步方法未等待:你之前调用CopyToAsync未添加await关键字,内存流还未写入完成就调用ToArray,导致拿到的内容不完整
  • 客户端缺失必填字段:上传的ByteArrayContent的ContentDisposition未设置Name属性,导致ASP.NET Core默认表单解析无法识别为文件项,因此Request.Form.Files为空
  • 直接读取Body内容无效:Request.Body存储的是完整的multipart表单报文,包含分隔符、请求头字段等附加内容,不是纯文件字节,直接读取无法直接使用

修正方案

1. 客户端代码调整

给ContentDisposition添加Name属性,同时可补充分块相关参数方便服务端处理:

fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
    FileName = Path.GetFileName(fileName),
    Name = "uploadChunk" // 表单解析依赖该字段识别文件项
};
// 可选:补充分块标识参数
content.Add(new StringContent("文件唯一ID"), "fileId");
content.Add(new StringContent("当前分块序号"), "chunkIndex");
content.Add(new StringContent("总分块数"), "totalChunk");

2. 服务端配置调整

在Program.cs中添加配置,取消请求大小限制(也可设置为自定义的分块最大值):

builder.WebHost.ConfigureKestrel(options =>
{
    // 取消请求大小限制,也可设置为具体数值,单位为字节
    options.Limits.MaxRequestBodySize = null;
});

3. 服务端分块读取实现(两种可选)

方案一:使用Request.Form.Files(最简单,适合大多数场景)

控制器代码示例:

[HttpPost("api/uploadFile")]
[DisableRequestSizeLimit]
public async Task<IActionResult> UploadChunk()
{
    // 手动触发表单解析
    var form = await Request.ReadFormAsync();
    var uploadFile = form.Files.FirstOrDefault();
    if (uploadFile == null)
    {
        return BadRequest("未获取到上传分块");
    }
    // 读取分块字节
    using var chunkMs = new MemoryStream();
    await uploadFile.CopyToAsync(chunkMs);
    var chunkBytes = chunkMs.ToArray();

    // 此处添加分块处理逻辑:比如按文件标识+分块序号存储临时文件,所有分块上传完成后合并为完整文件
    return Ok();
}

方案二:使用MultipartReader(低内存占用,适合超大分块场景)

无需依赖表单解析,直接从请求流读取内容:

[HttpPost("api/uploadFile")]
[DisableRequestSizeLimit]
public async Task<IActionResult> UploadChunk()
{
    var contentType = MediaTypeHeaderValue.Parse(Request.ContentType);
    var boundary = MultipartRequestHelper.GetBoundary(contentType, 1024);
    var reader = new MultipartReader(boundary, Request.Body);
    
    var section = await reader.ReadNextSectionAsync();
    byte[] chunkBytes = null;
    while (section != null)
    {
        if (ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var cd)
            && cd.IsFileDisposition())
        {
            using var chunkMs = new MemoryStream();
            await section.Body.CopyToAsync(chunkMs);
            chunkBytes = chunkMs.ToArray();
            break;
        }
        section = await reader.ReadNextSectionAsync();
    }

    if (chunkBytes == null)
    {
        return BadRequest("未获取到上传分块");
    }
    // 此处添加分块处理逻辑
    return Ok();
}

提示:实际生产使用时,建议客户端额外上传文件唯一标识、当前分块序号、总分块数三个参数,服务端可根据参数暂存分块,所有分块上传完成后按序号合并即可得到完整文件。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:39:05