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

Microsoft Graph发送带附件邮件报错:Content-Range头字节无效

解决Microsoft Graph上传附件时的Content-Range头错误

我之前也碰到过类似的问题,你遇到的Invalid total bytes specified in the Content-Range header错误,核心原因是Content-Range头的格式不正确,或者没有正确关联到上传会话的请求中。结合你提到的已经尝试创建ContentRangeHeaderValue但不知道怎么关联的情况,我给你一步步拆解解决方法:

1. 先明确Microsoft Graph大附件上传的核心流程

上传带附件的邮件时,如果附件较大(通常超过4MB),需要走「创建上传会话 → 分块上传」的流程,每个分块请求都必须携带正确的Content-Range头,告诉Graph当前上传的是文件的哪一部分,以及文件的总大小。

2. 正确实例化ContentRangeHeaderValue

首先要确保你创建的ContentRangeHeaderValue参数是准确的:

  • 第一个参数:当前分块的起始字节(从0开始)
  • 第二个参数:当前分块的结束字节(起始字节 + 当前块的字节数 - 1,因为是闭区间)
  • 第三个参数:文件的总字节数(必须和创建上传会话时指定的Size一致)

举个例子,如果文件总大小是10240字节,当前上传的是第一块(0-32767字节,32KB),那实例化代码应该是:

var contentRange = new ContentRangeHeaderValue(0, 32767, 10240);

3. 将ContentRangeHeaderValue关联到上传请求

创建好ContentRangeHeaderValue后,你需要把它添加到分块上传请求的Headers中。以下是完整的C#代码示例(假设你用的是Microsoft Graph .NET SDK):

第一步:创建上传会话

// 先获取文件的实际总大小
long fileTotalSize = new FileInfo("your-file-path").Length;

// 创建上传会话,这里的Size必须和文件实际大小一致
var uploadSession = await graphClient.Me.Messages[messageId].Attachments
    .CreateUploadSession(new AttachmentItem
    {
        AttachmentType = AttachmentType.File,
        Name = "your-attachment-name.ext",
        Size = fileTotalSize // 关键:必须是文件真实总字节数
    })
    .Request()
    .PostAsync();

第二步:分块上传并关联Content-Range

using var fileStream = new FileStream("your-file-path", FileMode.Open);
int chunkSize = 320 * 1024; // 推荐用320KB的分块大小,符合Graph的要求
byte[] buffer = new byte[chunkSize];
long bytesUploaded = 0;

while (bytesUploaded < fileTotalSize)
{
    int bytesRead = fileStream.Read(buffer, 0, chunkSize);
    var chunkContent = new ByteArrayContent(buffer, 0, bytesRead);

    // 设置Content-Range头
    var contentRange = new ContentRangeHeaderValue(
        bytesUploaded, 
        bytesUploaded + bytesRead - 1, 
        fileTotalSize
    );
    chunkContent.Headers.ContentRange = contentRange;

    // 发送分块上传请求
    var uploadRequest = new HttpRequestMessage(HttpMethod.Put, uploadSession.UploadUrl)
    {
        Content = chunkContent
    };
    var uploadResponse = await graphClient.HttpProvider.SendAsync(uploadRequest);
    
    // 确保请求成功
    uploadResponse.EnsureSuccessStatusCode();

    bytesUploaded += bytesRead;
}

4. 常见错误排查点

  • 总字节数不匹配:创建上传会话时的AttachmentItem.Size必须和文件实际大小完全一致,哪怕差1字节都会触发这个错误
  • Content-Range格式错误:结束字节不能超过总字节数,比如总大小是1000,结束字节不能是1000(应该是999)
  • 遗漏Content-Range头:每个分块PUT请求都必须携带这个头,不能只在第一个请求里加
  • 文件流读取异常:确认文件流的Length是正确的,没有因为文件权限、损坏等原因导致长度为0(你提到附件不为零,但还是要再确认下)

如果是用其他语言(比如JavaScript),原理是一样的:在PUT请求的headers里手动设置Content-Range: bytes 0-32767/10240这样的格式即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 18:02:26