Google drive api 谷歌硬盘为何回归';无法分析内容范围标头。';?
以下是我的简单酒窝代码,用于恢复(可能)中断的谷歌硬盘上传:Google drive api 谷歌硬盘为何回归';无法分析内容范围标头。';?,google-drive-api,dotnet-httpclient,Google Drive Api,Dotnet Httpclient,以下是我的简单酒窝代码,用于恢复(可能)中断的谷歌硬盘上传: Using message = New ByteArrayContent(New Byte() {}) message.Headers.ContentRange = New Headers.ContentRangeHeaderValue(Session.Size) 'message.Headers.TryAddWithoutValidation("Content-Range", "bytes */*")
Using message = New ByteArrayContent(New Byte() {})
message.Headers.ContentRange = New Headers.ContentRangeHeaderValue(Session.Size)
'message.Headers.TryAddWithoutValidation("Content-Range", "bytes */*")
Dim response = Await PutAsync("https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=" & Session.Code, message)
Dim msg = Await response.Content.ReadAsStringAsync
'ERR: this is always 'Failed to parse Content-Range header.'
Dim position = 0L
If response.Headers.Contains("Range") Then
Dim range = response.Headers.GetValues("Range")
position = range.First.SplitPlus("-")(1)
End If
但谷歌不断回归
无法分析内容范围标头
我手动检查了标题,看起来还可以:
Content-Range: bytes */389587456
Content-Length: 0
可能是什么事
我尝试的是:
使用StringContent
而不是ByteArrayContent
使用不带验证的tryadd
和*/*
都不行
带着好感
更新
我试着从头上传一个新文件。新鲜上传。代码如下:
If response.StatusCode = 308 Then
Using fileStream = New ThrottledFileStream(Session.FilePath)
fileStream.Position = position
Using Content = New StreamContent(fileStream)
Content.Headers.ContentRange = New Headers.ContentRangeHeaderValue(position, Session.Size, Session.Size)
Using Timer = New Timer(Sub(o)
Dim ps As Long
If fileStream.CanRead Then ps = fileStream.Position
Progress.Invoke(New CloudUploadState With {.Response = response, .Position = ps})
End Sub, Nothing, 0, 20000)
Dim finishResponse = Await Put("https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=" & Session.Code, Content)
Progress.Invoke(New CloudUploadState With {.Response = finishResponse})
End Using
End Using
End Using
End If
但我得到了完全相同的响应:未能解析内容范围头。
这是在上传整个文件之后(基于返回所需的时间和文件团队的位置)
我的要求怎么了
谢谢
为了完整起见,这里基本上是完整的代码。我非常感谢您的帮助或指点:
Public Async Function Upload(Session As DriveSession, Progress As Action(Of CloudUploadState)) As Task Implements ICloudStorage.Upload
Await EnsureCredentials()
If Session.Code Is Nothing Then
Dim path = Session.FilePath
If Debugger.IsAttached Then path = IO.Path.Combine("Test", path.Replace("\\", "\").Replace(":", ""))
Dim currentFolderId = ""
For Each nextFolderName In path.Split("\")
Dim url = $"https://www.googleapis.com/drive/v3/files?fields=files(name,id)&q=name='{nextFolderName}'"
If currentFolderId <> "" Then url &= $" and '{currentFolderId}' in parents"
If path.EndsWith("\" & nextFolderName) Then
Dim metadata = New JObject From {{"name", IO.Path.GetFileName(path)}}
metadata("parents") = New JArray From {currentFolderId}
Using message = New StringContent(metadata.ToString, Encoding.UTF8, "application/json")
message.Headers.Add("X-Upload-Content-Type", GetExtMime(IO.Path.GetExtension(path).LeftCut(".")))
message.Headers.Add("X-Upload-Content-Length", Session.Size)
Dim response = Await Post($"https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable", message)
Session.Code = response.Headers.Location.QueryParams("upload_id")
Using d = GetSystemContext(True)
Dim ds = d.Find(Of DriveSession)(Session.ID)
ds.Code = Session.Code
d.SaveChanges()
End Using
End Using
'End If
Else
url &= " and mimeType = 'application/vnd.google-apps.folder'"
Dim ret = Await GetString(url)
Dim files = ParseResponse(ret)
If files.Count > 1 Then DevError("identical names")
If files.Any Then
currentFolderId = files.First.Id
Else
Dim data = New JObject From {{"name", nextFolderName}, {"mimeType", "application/vnd.google-apps.folder"}}
If currentFolderId IsNot Nothing Then data.Add(New JProperty("parents", New JArray(currentFolderId)))
Using content = New StringContent(data.ToString, Encoding.UTF8, "application/json")
Using response = Await Post("https://www.googleapis.com/drive/v3/files", content)
Dim message = Await response.Content.ReadAsStringAsync
currentFolderId = JObject.Parse(message).Value(Of String)("id")
End Using
End Using
End If
End If
Next
End If
Using message = New ByteArrayContent(New Byte() {})
message.Headers.ContentRange = New Headers.ContentRangeHeaderValue(Session.Size)
Dim response = Await PutAsync("https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=" & Session.Code, message)
Dim position = 0L
If response.Headers.Contains("Range") Then
Dim range = response.Headers.GetValues("Range")
position = range.First.SplitPlus("-")(1)
End If
Progress.Invoke(New CloudUploadState With {.Response = response, .Position = position})
If response.StatusCode = 308 Then
Using fileStream = New ThrottledFileStream(Session.FilePath)
fileStream.Position = position
Using Content = New StreamContent(fileStream)
Content.Headers.ContentRange = New Headers.ContentRangeHeaderValue(position, Session.Size, Session.Size)
Using Timer = New Timer(Sub(o)
Dim ps As Long
If fileStream.CanRead Then ps = fileStream.Position
Progress.Invoke(New CloudUploadState With {.Response = response, .Position = ps})
End Sub, Nothing, 0, 30000)
Dim finishResponse = Await PutAsync("https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=" & Session.Code, Content)
Progress.Invoke(New CloudUploadState With {.Response = finishResponse})
End Using
End Using
End Using
End If
End Using
End Function
Public异步函数Upload(会话作为DriveSession,进度作为Action(CloudUploadState))作为任务实现ICloudStorage.Upload
等待重新定义()
如果Session.Code什么都不是,那么
Dim path=Session.FilePath
如果Debugger.IsAttached,则path=IO.path.Combine(“测试”,path.Replace(“\\”,“\”)。Replace(“:”,”)
Dim currentFolderId=“”
对于path.Split(“\”)中的每个下一个文件夹名
Dim url=$”https://www.googleapis.com/drive/v3/files?fields=files(name,id)&q=name='{nextFolderName}'
如果currentFolderId为“”,则url&=$和父级中的“{currentFolderId}”
如果path.EndsWith(“\”&nextFolderName)则
Dim metadata=来自{{“name”,IO.Path.GetFileName(Path)}的新作业对象
元数据(“父项”)=来自{currentFolderId}的新JArray
使用message=newstringcontent(metadata.ToString,Encoding.UTF8,“application/json”)
message.Headers.Add(“X-Upload-Content-Type”,GetExtMime(IO.Path.GetExtension(Path.LeftCut)(“.”))
message.Headers.Add(“X-Upload-Content-Length”,Session.Size)
Dim响应=等待发布($”https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable“,信息)
Session.Code=response.Headers.Location.QueryParams(“上传id”)
使用d=GetSystemContext(True)
Dim ds=d.Find(属于DriveSession)(Session.ID)
ds.Code=Session.Code
d、 SaveChanges()
终端使用
终端使用
"完"
其他的
url&=“和mimeType='application/vnd.google apps.folder'”
Dim ret=等待获取字符串(url)
Dim文件=解析响应(ret)
如果files.Count>1,则删除错误(“相同的名称”)
如果有文件,那么有吗
currentFolderId=files.First.Id
其他的
Dim data=来自{{“name”,nextFolderName},{“mimeType”,“application/vnd.google apps.folder”}的新作业对象
如果currentFolderId不是空的,那么data.Add(New JProperty(“parents”,New JArray(currentFolderId)))
使用content=newstringcontent(data.ToString,Encoding.UTF8,“application/json”)
使用response=wait Post(“https://www.googleapis.com/drive/v3/files“,内容)
Dim消息=wait response.Content.ReadAsStringAsync
currentFolderId=JObject.Parse(message).Value(字符串)(“id”)
终端使用
终端使用
如果结束
如果结束
下一个
如果结束
使用message=newbytearraycontent(newbyte(){})
message.Headers.ContentRange=新的Headers.ContentRangeHeaderValue(Session.Size)
Dim响应=等待PutAsync(“https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=“&会话。代码,消息)
变光位置=0升
如果response.Headers.Contains(“范围”),则
Dim range=response.Headers.GetValues(“范围”)
位置=范围.First.SplitPlus(“-”)1
如果结束
Invoke(带有{.Response=Response、.Position=Position}的新CloudUploadState)
如果response.StatusCode=308,则
使用fileStream=New ThrottledFileStream(Session.FilePath)
fileStream.Position=Position
使用内容=新的流内容(文件流)
Content.Headers.ContentRange=新的Headers.ContentRangeHeaderValue(位置、会话.Size、会话.Size)
使用计时器=新计时器(Sub(o)
将ps调暗为长
如果fileStream.CanRead,则ps=fileStream.Position
Invoke(带有{.Response=Response、.Position=ps}的新CloudUploadState)
末端接头,无,0,30000)
Dim finishResponse=等待PutAsync(“https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&upload_id=“&会话。代码,内容)
Invoke(带有{.Response=finishResponse}的新CloudUploadState)
终端使用
终端使用
终端使用
如果结束
终端使用
端函数
好的。知道了。请求“content Length:0”中缺少,我不熟悉vb.net,但下面是一个可恢复上传到Google Drive的示例代码:可能这些链接也有帮助:您好。第一个和最后一个链接使用外部SDK,我正试图避免这种情况。第二个链接显示了一个使用Post的示例,它违反了谷歌的指令,在任何情况下都不起作用。还有其他想法吗?我不是苏