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

使用Microsoft Graph API批量上传文件至OneDrive后内容无法打开求助

问题诊断与修复方案

核心问题:文件内容上传格式错误

你当前的代码把文件二进制编码为Base64后,用JSON对象{contentBytes: "..."}包裹发送,但Microsoft Graph API的/content端点要求直接发送原始二进制数据,不需要JSON包装。这种错误格式导致文件内容被解析为JSON文本而非原始文件数据,所以文件能创建但无法正常打开。

其他逻辑问题

  • 批次大小管理混乱:初始定义batchSize=20,但循环中又执行batchSize++,导致批次计数逻辑完全错误,可能出现提前或延迟发送批次的情况。
  • 文件流读取不完整:fileStream.Read()不能保证一次性读取所有字节,存在丢失部分文件内容的风险。
  • 请求构建冗余:通过.Content.Request().GetHttpRequestMessage()获取请求后修改方法和内容,不如直接构建PUT请求更简洁。

修正后的代码实现

public async Task BatchUploadFileAsync(string DriveID, GetAllFilesToUpload filesToUpload)
{
    const int batchSize = 20; // 固定批次大小,避免变量复用混乱
    var batchesOfFiles = new List<List<FileDatatoUpload>>();
    var currentBatch = new List<FileDatatoUpload>();

    // 先按批次分组文件
    foreach (var file in filesToUpload.Files)
    {
        currentBatch.Add(new FileDatatoUpload
        {
            FormFile = file.FormFile,
            Folder = file.Folder,
            TypeOfDocument = file.TypeOfDocument,
            SchoolYear = file.SchoolYear,
            Curriculum = file.Curriculum,
            Language = file.Language,
            Semestre = file.Semestre,
            PathStudent = file.PathStudent,
            AcademicYear = file.AcademicYear,
            Student = file.Student
        });

        if (currentBatch.Count == batchSize)
        {
            batchesOfFiles.Add(currentBatch);
            currentBatch = new List<FileDatatoUpload>();
        }
    }

    if (currentBatch.Count > 0)
    {
        batchesOfFiles.Add(currentBatch);
    }

    try
    {
        foreach (var batchFiles in batchesOfFiles)
        {
            var batchRequestContent = new BatchRequestContent();
            foreach (var file in batchFiles)
            {
                // 确保完整读取文件流
                using (var memoryStream = new MemoryStream())
                {
                    await file.FormFile.CopyToAsync(memoryStream);
                    memoryStream.Position = 0; // 重置流位置到起始点

                    // 直接用文件流作为请求内容,无需JSON包装
                    var streamContent = new StreamContent(memoryStream);
                    // 设置正确的Content-Type,若无法获取可设为application/octet-stream
                    streamContent.Headers.ContentType = MediaTypeHeaderValue.Parse(file.FormFile.ContentType);

                    // 构建PUT请求上传文件内容
                    var requestUrl = _graphServiceClientApp.Users["userId"].Drive.Root
                        .ItemWithPath(Path.Combine(file.PathStudent))
                        .Content.Request().RequestUrl;

                    var request = new HttpRequestMessage(HttpMethod.Put, requestUrl)
                    {
                        Content = streamContent
                    };

                    // 添加到批次请求
                    batchRequestContent.AddBatchRequestStep(request);
                }
            }

            // 发送当前批次
            await _graphServiceClientApp.Batch.Request().PostAsync(batchRequestContent);
        }
    }
    catch (ServiceException ex)
    {
        Console.WriteLine($"Error uploading: {ex.ToString()}");
    }
}

关键修正点说明

  • 直接发送二进制流:使用StreamContent包装文件流作为请求内容,完全符合Graph API的要求。
  • 修复批次逻辑:用常量定义批次大小,每个批次单独创建BatchRequestContent,避免交叉污染。
  • 可靠读取文件流:使用CopyToAsync将上传文件复制到MemoryStream,确保完整读取所有内容。
  • 正确设置Content-Type:保留原文件的MIME类型,帮助Graph API正确识别文件类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 09:47:33