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

如何在外部.NET Web应用中用Microsoft Graph上传大文件至文档库?

使用Microsoft Graph分块上传大文件到文档库

我完全懂你的痛点——小文件能顺利上传,但超过4MB就报错,这是因为Graph的直接/content上传接口默认有4MB的大小限制。而createUploadSession就是微软官方提供的大文件分块上传解决方案,我给你一步步拆解实现,结合你现有的.NET HttpClient代码来调整:

核心思路

分块上传分为两步:先创建一个上传会话(拿到专属的上传URL),然后把大文件拆成多个小块,依次上传到这个会话URL,最后完成上传。


第一步:创建上传会话

这一步的目的是获取一个临时的上传会话URL,后续所有分块都通过这个URL上传,同时可以指定文件的冲突处理策略(比如覆盖已存在的文件)。

代码示例

using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;

// 替换成你的实际参数
string driveId = "{mydriveid}";
string localFilePath = @"C:\你的大文件路径\bigfile.zip";
string fileName = Path.GetFileName(localFilePath);
long totalFileSize = new FileInfo(localFilePath).Length;

// 1. 构建创建会话的请求
string createSessionUrl = $"https://graph.microsoft.com/v1.0/drives/{driveId}/items/root:/{fileName}:/createUploadSession";

// 请求体:指定冲突策略和文件名
var sessionRequestBody = new
{
    item = new
    {
        @microsoft.graph.conflictBehavior = "replace", // 可选值:replace/rename/fail
        name = fileName
    }
};

using (HttpClient client = new HttpClient())
{
    // 记得添加你的Bearer令牌
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "你的访问令牌");
    
    var content = new StringContent(JsonConvert.SerializeObject(sessionRequestBody), Encoding.UTF8, "application/json");
    var response = await client.PostAsync(createSessionUrl, content);
    response.EnsureSuccessStatusCode(); // 处理请求失败的情况
    
    // 解析响应,拿到上传会话URL
    var sessionResponse = await response.Content.ReadAsAsync<dynamic>();
    string uploadSessionUrl = sessionResponse.uploadUrl;
    
    // 下一步:用这个uploadSessionUrl进行分块上传
    await UploadFileInChunks(uploadSessionUrl, localFilePath, totalFileSize);
}

第二步:分块上传文件内容

微软推荐的分块大小是5MB到100MB,最小不能小于5MB(最后一块除外)。我们需要读取文件的字节流,拆分后逐个上传,同时通过Content-Range请求头告诉Graph当前块的范围。

分块上传的方法实现

private static async Task UploadFileInChunks(string uploadSessionUrl, string localFilePath, long totalFileSize)
{
    const int chunkSize = 5 * 1024 * 1024; // 5MB分块
    byte[] buffer = new byte[chunkSize];
    long uploadedBytes = 0;

    using (FileStream fileStream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read))
    {
        using (HttpClient client = new HttpClient())
        {
            while (uploadedBytes < totalFileSize)
            {
                int bytesRead = await fileStream.ReadAsync(buffer, 0, chunkSize);
                if (bytesRead == 0) break;

                // 计算当前块的字节范围
                long startByte = uploadedBytes;
                long endByte = uploadedBytes + bytesRead - 1;
                string contentRangeHeader = $"bytes {startByte}-{endByte}/{totalFileSize}";

                // 构建分块的请求内容
                var chunkContent = new ByteArrayContent(buffer, 0, bytesRead);
                chunkContent.Headers.ContentRange = new ContentRangeHeaderValue(startByte, endByte, totalFileSize);

                // 发送PUT请求到会话URL
                var chunkResponse = await client.PutAsync(uploadSessionUrl, chunkContent);

                if (chunkResponse.StatusCode == System.Net.HttpStatusCode.Created)
                {
                    // 上传完成,返回文件的详细信息
                    var uploadedFile = await chunkResponse.Content.ReadAsAsync<dynamic>();
                    Console.WriteLine($"大文件上传成功!文件ID:{uploadedFile.id}");
                    break;
                }
                else if (chunkResponse.StatusCode == System.Net.HttpStatusCode.Accepted)
                {
                    // 继续上传下一块,更新已上传字节数
                    var sessionStatus = await chunkResponse.Content.ReadAsAsync<dynamic>();
                    uploadedBytes = long.Parse(sessionStatus.nextExpectedRanges[0].Split('-')[0]);
                }
                else
                {
                    // 处理上传错误
                    chunkResponse.EnsureSuccessStatusCode();
                }
            }
        }
    }
}

关键注意事项

  • 权限要求:你的访问令牌需要拥有Files.ReadWrite(OneDrive)或Sites.ReadWrite.All(SharePoint文档库)的权限
  • 会话有效期:上传会话默认有效期是24小时,如果上传中断,可以复用这个会话继续上传未完成的块
  • 分块大小:不要设置小于5MB的分块(最后一块除外),否则会报错
  • 冲突处理:根据业务需求调整@microsoft.graph.conflictBehavior的值,比如rename会自动给重复文件名加后缀,fail会直接返回错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:45:19