Reputation: 2424
I'm working with the Google APIs for the first time and I'm having problems trying to download files with the File object "downloadUrl" property. I'm currently using the "Service Account" option with the associated service account email and P12 certificate.
However, the URL returned "https://doc-08-68-docs.googleusercontent.com/docs/securesc/bteg36c1tifegg79l2ov17og25612tet/gk7kn52ahe4d0to7d6hte9f0f2hv47e4/1434132000000/11750183130219432819/11750183130219432819/0BziIKv2_NWCxc3RhcnRlcl9maWxl?e=download&gd=true" returns a 401 - Unauthorized response.
Imports System.Collections.Generic
Imports System.Security.Cryptography.X509Certificates
Imports System.IO
Imports Google.Apis.Drive.v2
Imports Google.Apis.Drive.v2.Data
Imports Google.Apis.Services
Imports Google.Apis.Auth.OAuth2
Namespace Videos
Partial Class List
Inherits System.Web.UI.UserControl
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Const serviceAccountEmail As String = "@developer.gserviceaccount.com"
Dim certificate = New X509Certificate2(
Server.MapPath("~/bin/key.p12"),
"notasecret",
X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet Or X509KeyStorageFlags.Exportable
)
Dim credential = New ServiceAccountCredential(
New ServiceAccountCredential.Initializer(serviceAccountEmail) With {
.Scopes = New String() {DriveService.Scope.Drive}
}.FromCertificate(certificate)
)
Dim service = New DriveService(
New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = "LexVid-VideoEncode/1.0"
}
)
UxFiles.DataSource = RetrieveAllFiles(service)
UxFiles.DataBind()
End Sub
Public Shared Function RetrieveAllFiles(service As DriveService) As List(Of Data.File)
Dim result = New List(Of Data.File)()
Dim request As FilesResource.ListRequest = service.Files.List()
Do
Try
Dim files As FileList = request.Execute()
result.AddRange(files.Items)
request.PageToken = files.NextPageToken
Catch e As Exception
request.PageToken = Nothing
End Try
Loop While (Not String.IsNullOrEmpty(request.PageToken))
Return result
End Function
Public Shared Function DownloadFile(ByVal service As DriveService, ByVal file As Data.File) As System.IO.Stream
If (Not String.IsNullOrEmpty(file.DownloadUrl)) Then
Try
Dim x = service.HttpClient.GetByteArrayAsync(file.DownloadUrl)
Dim result As [Byte]() = x.Result
Return New MemoryStream(result)
Catch e As Exception
Return Nothing
End Try
Else
Return Nothing
End If
End Function
Protected Sub UxFiles_ItemDataBound(ByVal sender As Object, ByVal e As ListViewItemEventArgs) Handles UxFiles.ItemDataBound
Dim dataItem = CType(e.Item.DataItem, Data.File)
Dim file = CType(e.Item.FindControl("UxFile"), HyperLink)
file.NavigateUrl = dataItem.DownloadUrl
file.Text = dataItem.Title
End Sub
End Class
End Namespace
Upvotes: 0
Views: 1054
Reputation: 2424
I got this resolved through some trial and error. Although I'm building the links manually now, so the request token isn't even necessary anymore. However, I'm posting here in case anyone else is looking to resolve a similar issue.
Imports System.Collections.Generic
Imports System.Security.Cryptography.X509Certificates
Imports System.IO
Imports System.Threading
Imports Google.Apis.Drive.v2
Imports Google.Apis.Drive.v2.Data
Imports Google.Apis.Services
Imports Google.Apis.Auth.OAuth2
Namespace Videos
Partial Class List
Inherits System.Web.UI.UserControl
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Const serviceAccountEmail As String = "@developer.gserviceaccount.com"
Dim certificate = New X509Certificate2(
Server.MapPath("~/bin/key.p12"),
"notasecret",
X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet Or X509KeyStorageFlags.Exportable
)
Dim credential As ServiceAccountCredential = New ServiceAccountCredential(
New ServiceAccountCredential.Initializer(serviceAccountEmail) With {
.Scopes = New String() {DriveService.Scope.Drive}
}.FromCertificate(certificate)
)
If (credential.RequestAccessTokenAsync(CancellationToken.None).Result) Then
Dim service = New DriveService(
New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = "LexVid-VideoEncode/1.0"
}
)
UxFiles.DataSource = RetrieveAllFiles(service)
UxFiles.DataBind()
End If
End Sub
Public Shared Function RetrieveAllFiles(service As DriveService) As List(Of Data.File)
Dim result = New List(Of Data.File)()
Dim request As FilesResource.ListRequest = service.Files.List()
Do
Try
Const folderID As String = "0B5RLR6VRZsR4fkE5QjVFajg2dzZOMXZLYkNZUVdGbEtNODF0XzVBVGdjMW9ISDF5OE9kM0E"
request.Q = String.Format("'{0}' in parents and trashed=false", folderID)
Dim files As FileList = request.Execute()
result.AddRange(files.Items)
request.PageToken = files.NextPageToken
Catch e As Exception
request.PageToken = Nothing
End Try
Loop While (Not String.IsNullOrEmpty(request.PageToken))
Return result
End Function
Protected Sub UxFiles_ItemDataBound(ByVal sender As Object, ByVal e As ListViewItemEventArgs) Handles UxFiles.ItemDataBound
Dim dataItem = CType(e.Item.DataItem, Data.File)
Const folderID As String = "0B5RLR6VRZsR4fkE5QjVFajg2dzZOMXZLYkNZUVdGbEtNODF0XzVBVGdjMW9ISDF5OE9kM0E"
Dim file = CType(e.Item.FindControl("UxFile"), HyperLink)
file.NavigateUrl = String.Format("http://googledrive.com/host/{0}/{1}", folderID, dataItem.Title)
' Large files prompt for virus scan; no bypass available.
' file.NavigateUrl = String.Format("https://drive.google.com/uc?export=download&id={0}", dataItem.Id)
file.Text = dataItem.Title
End Sub
End Class
End Namespace
Upvotes: 1