首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >OneDrive API可解析上传url没有响应

OneDrive API可解析上传url没有响应
EN

Stack Overflow用户
提问于 2017-08-23 03:55:35
回答 1查看 555关注 0票数 1

我一直在开发一个OneDrive桌面客户端应用程序,因为内置在windows中的应用程序一直让我失望,原因我无法弄清楚。我通过一个C#在HttpClient中使用REST。

所有对onedrive端点的请求都正常工作(下载、上传小文件等)。直到最近(大约两天前),上传大型文件的工作还不错。我获得上传会话URL并开始将数据上传到它,但是在成功地将两块数据上传到它之后(202个响应),第三个请求和超时(通过HttpClient),无论是一个GET获取状态,还是一个PUT来上传数据。创建会话的POST仍然有效。

我尝试过:获得一个新的ClientId,登录到一个新的Microsoft帐户,将代码恢复到已知的工作状态,以及重新克隆git存储库。

在PostMan中,我可以完成创建会话和上传块的整个过程,而不会遇到这个问题,但是如果我将应用程序从OneDrive API检索的上传URL并试图在PostMan中将PUT数据发送给它,服务器将不会响应(除非请求无效,它有时会告诉我)。对这个URL的后续GET请求也没有响应。

下面是所有经过身份验证后转到OneDrive API的请求的日志:https://pastebin.com/qRrw2Sb5

以下是相关代码:

代码语言:javascript
运行
复制
//first, create an upload session
var httpResponse = await _httpClient.StartAuthenticatedRequest(url, HttpMethod.Post).SendAsync(ct);
if (httpResponse.StatusCode != HttpStatusCode.OK)
{
    return new HttpResult<IRemoteItemHandle>(httpResponse, null);
}


//get the upload URL
var uploadSessionRequestObject = await HttpClientHelper.ReadResponseAsJObjectAsync(httpResponse);

var uploadUrl = (string)uploadSessionRequestObject["uploadUrl"];
if (uploadUrl == null)
{
    Debug.WriteLine("Successful OneDrive CreateSession request had invalid body!");
    //TODO: what to do here?
}

//the length of the file total
var length = data.Length;

//setup the headers
var headers = new List<KeyValuePair<string, string>>()
{
    new KeyValuePair<string, string>("Content-Length", ""),
    new KeyValuePair<string, string>("Content-Range","")
};

JObject responseJObject;
//the response that will be returned
HttpResponseMessage response = null;

//get the chunks
List<Tuple<long, long>> chunks;
do
{

    HttpResult<List<Tuple<long, long>>> chunksResult;
    //get the chunks
    do
    {
        chunksResult = await RetrieveLargeUploadChunksAsync(uploadUrl, _10MB, length, ct);
        //TODO: should we delay on failure?
    } while (chunksResult.Value == null);//keep trying to get thre results until we're successful

    chunks = chunksResult.Value;

    //upload each fragment
    var chunkStream = new ChunkedReadStreamWrapper(data);
    foreach (var fragment in chunks)
    {
        //setup the chunked stream with the next fragment
        chunkStream.ChunkStart = fragment.Item1;

        //the size is one more than the difference (because the range is inclusive)
        chunkStream.ChunkSize = fragment.Item2 - fragment.Item1 + 1;

        //setup the headers for this request
        headers[0] = new KeyValuePair<string, string>("Content-Length", chunkStream.ChunkSize.ToString());
        headers[1] = new KeyValuePair<string, string>("Content-Range", $"bytes {fragment.Item1}-{fragment.Item2}/{length}");

        //submit the request until it is successful
        do
        {
            //this should not be authenticated
            response = await _httpClient.StartRequest(uploadUrl, HttpMethod.Put)
                .SetContent(chunkStream)
                .SetContentHeaders(headers)
                .SendAsync(ct);

        } while (!response.IsSuccessStatusCode); // keep retrying until success
    }

    //parse the response to see if there are more chunks or the final metadata
    responseJObject = await HttpClientHelper.ReadResponseAsJObjectAsync(response);

    //try to get chunks from the response to see if we need to retry anything
    chunks = ParseLargeUploadChunks(responseJObject, _10MB, length);
}
while (chunks.Count > 0);//keep going until no chunks left

所有的东西都会做注释说什么或名字暗示什么,但是很多方法/类都是我自己的,所以我很乐意解释任何可能不明显的事情。

我完全不知道这是怎么回事,希望能得到任何帮助。我正试着在星期六回到学校之前把这件事做完,现在没有时间去做了。

编辑:等待一段时间后,可以通过PostMan再次向上传URL发出请求。

编辑2: i不能在邮递员中复制这种超时现象。无论我是从我的应用程序中获得上传URL,还是从另一个邮递员请求中获得,以及我的应用程序中的上传是否停止,我似乎都可以通过Postman上传我想要的所有片段。

编辑3:这种没有响应的行为在读取内容流之前就开始了。

编辑4:查看WireShark上的数据包信息,前两个块几乎是相同的,但是只有“重发”数据包出现在第三个块上。

EN

回答 1

Stack Overflow用户

发布于 2017-09-11 01:08:00

因此,经过3周的不同级别的测试,我终于发现了这个问题,这与OneDrive Graph api几乎没有任何关系。问题是,在发出Http请求时,我使用的是HttpCompletionOption.ResponseHeadersRead,而不是在发送下一个响应之前读取响应。这意味着HttpClient阻止我发送更多的请求,直到我阅读了旧的回复。这很奇怪,因为它允许我在锁定之前发送两个请求。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45830398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档