使用 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 我已经创建了一个快速的小应用程序来展示它是如何工作的。看看下面的要点,看看它与你实际做的相比如何:
我尝试通过 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 我已经创建了一个快速的小应用程序来展示它是如何工作的。看看下面的要点,看看它与你实际做的相比如何: