使用MS Graph API分块上传时RestSharp报无效Content-Range头错误
解决MS Graph API分块上传最后一块Content-Range错误的方案
问题根源分析
你的代码存在两个关键问题,直接导致最后一块上传触发请求头错误:
- Body的ContentType不匹配:你用
ContentType.Json添加二进制文件流,实际发送的内容格式与声明的Content-Type: application/octet-stream不符,最后一块的字节校验失败,引发请求头错误。 - 缺失必要的Content-Length头:MS Graph API分块上传要求必须携带
Content-Length,明确当前分块的字节数,否则服务端无法正确校验内容范围。
修正后的代码
using (var fileStream = File.OpenRead(attachmentLocation)) { var buffer = new byte[1000 * 1024]; int bytesRead; long totalBytesUploaded = 0; long totalFileLength = fileStream.Length; while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0) { var requestEmail = new RestRequest(upload_url, Method.Put); requestEmail.AddHeader("Content-Type", "application/octet-stream"); // 添加Content-Length,明确当前分块的字节数 requestEmail.AddHeader("Content-Length", bytesRead.ToString()); // 计算当前分块的起始和结束索引 long rangeStart = totalBytesUploaded; long rangeEnd = totalBytesUploaded + bytesRead - 1; // 兜底确保结束索引不超过总长度-1,符合HTTP规范 if (rangeEnd >= totalFileLength) { rangeEnd = totalFileLength - 1; } requestEmail.AddHeader("Content-Range", $"bytes {rangeStart}-{rangeEnd}/{totalFileLength}"); // 用正确的二进制类型添加请求体,仅上传实际读取的字节 requestEmail.AddParameter("application/octet-stream", buffer.Take(bytesRead).ToArray(), ParameterType.RequestBody); var response = client.Execute(requestEmail); // 可添加响应校验,提前捕获异常 if (!response.IsSuccessful) { // 日志记录或错误处理逻辑 break; } totalBytesUploaded += bytesRead; } }
核心修正说明
- 对齐请求体与Content-Type:使用
application/octet-stream作为请求体的类型,并且只上传实际读取的bytesRead长度字节,避免buffer末尾空字节干扰校验。 - 恢复Content-Length头:服务端依赖这个头确认分块大小,缺失会导致内容范围校验失败。
- 边界索引兜底:虽然计算逻辑本身正确,但添加判断确保最后一块的结束索引严格等于总长度-1,完全符合HTTP Content-Range的格式规范。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

