使用 BITS-Protocol 将文件上传到 OneDrive 时出现 400 错误

400 Error while Uploading files to OneDrive with BITS-Protocol

我尝试通过 BITS 将文件上传到 OneDrive (OneDrive Large File Upload API)。

我可以创建一个会话,但是当我想上传第一个片段时,我在读取响应时收到带有 400 HTTP-Error(错误请求)的 WebException。 异常中没有更多信息。 我的代码是这样的:

string requestString = String.Format("https://cid-{0}.users.storage.live.com/items/{1}/{2}", userId, folderId, fileName);

WebRequest webRequest = WebRequest.Create(requestString);
webRequest.Headers.Add("X-Http-Method-Override", "BITS_POST");
webRequest.Headers.Add("Authorization", "Bearer " + accessToken);
webRequest.Headers.Add("BITS-Packet-Type", "Fragment");
webRequest.Headers.Add("BITS-Session-Id", sessionId);

webRequest.Headers.Add("Content-Range", String.Format("bytes {0}-{1}/{2}", contentOffset, (contentFragment.Count() + contentOffset), totalContentLength));

webRequest.ContentLength = contentFragment.Count();

webRequest.Method = "POST";


webRequest.GetRequestStream().Write(contentFragment.ToArray(), 0, contentFragment.Count());

WebResponse webResponse = webRequest.GetResponse() as WebResponse;

这是一个屏幕截图,用于查看第一个请求的值,该请求已经失败:

github 项目中的评论强烈暗示 400 响应与错误的 Context-Range 和 ContentLength header 值有关。

从贴出的信息来看需要通灵调试,很不符合。您将片段大小报告为 contentLength,但实际上上传了一个 content.Count() 长的片段。不匹配的好机会,因此 400 错误。

假设 content 包含所有可上传的数据,我想出的第一个建议是使用:

webRequest.GetRequestStream().
   Write(content.ToArray(), contentOffset, contentLength);

而第二个,假设 content 只包含片段:

var length = content.Count();
webRequest.Headers.Add("Content-Range", String.Format("bytes {0}-{1}/{2}",
    contentOffset, contentOffset + length - 1, totalContentLength));
webRequest.ContentLength = length;

其中包含 Brad 建议的范围修正并记录在 RFC-2616,第 14.16 节

如果没有帮助,请更新您的问题以显示更多上下文。

我们已经看到了很多关于如何实施的问题 this process 我已经创建了一个快速的小应用程序来展示它是如何工作的。看看下面的要点,看看它与你实际做的相比如何:

https://gist.github.com/ificator/3460d7b9d0bff74eb0ff