【问题标题】:download file from google drive using asp.net使用asp.net从谷歌驱动器下载文件
【发布时间】:2015-08-26 07:10:07
【问题描述】:

我正在尝试使用以下代码从谷歌驱动器下载文件:

     public static Boolean downloadFile(string downloadurl, string _saveTo)
        {

            if (!String.IsNullOrEmpty(downloadurl))
            {
                try
                {
                  var x = service.HttpClient.GetByteArrayAsync(downloadurl);
                    byte[] arrBytes = x.Result;
                    System.IO.File.WriteAllBytes(_saveTo, arrBytes);
                    return true;
                }
                catch (Exception e)
                {
                    Console.WriteLine("An error occurred: " + e.Message);
                    return false;
                }
            }
            else
            {
                // The file doesn't have any content stored on Drive.
                return false;
            }
        }

调试上面的代码抛出异常如下:

?service.HttpClient.GetByteArrayAsync(downloadurl)
Id = 10, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}"
    AsyncState: null
    CancellationPending: false
    CreationOptions: None
    Exception: null
    Id: 10
    Result: null
    Status: WaitingForActivation

我正在尝试通过使用 Google API 控制台创建的服务帐户来执行此操作。

异常详情如下:

System.NullReferenceException was caught
  HResult=-2147467261
  Message=Object reference not set to an instance of an object.
  Source=System.Net.Http
  StackTrace:
       at System.Net.Http.Headers.HttpRequestHeaders.AddHeaders(HttpHeaders sourceHeaders)
       at System.Net.Http.HttpClient.PrepareRequestMessage(HttpRequestMessage request)
       at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
       at System.Net.Http.HttpClient.GetAsync(Uri requestUri, HttpCompletionOption completionOption, CancellationToken cancellationToken)
       at System.Net.Http.HttpClient.GetContentAsync[T](Uri requestUri, HttpCompletionOption completionOption, T defaultValue, Func`2 readAs)
       at System.Net.Http.HttpClient.GetByteArrayAsync(Uri requestUri)
       at System.Net.Http.HttpClient.GetByteArrayAsync(String requestUri)

【问题讨论】:

    标签: asp.net google-drive-api google-api-console


    【解决方案1】:

    你可以试试这个。
    link

    using Google.Apis.Authentication;
        using Google.Apis.Drive.v2;
        using Google.Apis.Drive.v2.Data;
    
        using System.Net;
    
        public class MyClass {
    
          public static System.IO.Stream DownloadFile(
              IAuthenticator authenticator, File file) {
            if (!String.IsNullOrEmpty(file.DownloadUrl)) {
              try {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
                    new Uri(file.DownloadUrl));
                authenticator.ApplyAuthenticationToRequest(request);
                HttpWebResponse response = (HttpWebResponse) request.GetResponse();
                if (response.StatusCode == HttpStatusCode.OK) {
                  return response.GetResponseStream();
                } else {
                  Console.WriteLine(
                      "An error occurred: " + response.StatusDescription);
                  return null;
                }
              } catch (Exception e) {
                Console.WriteLine("An error occurred: " + e.Message);
                return null;
              }
            } else {
              // The file doesn't have any content stored on Drive.
              return null;
            }
          }
        }
    

    【讨论】:

    • 如何传递验证器参数,因为我使用的服务帐户只需要服务电子邮件 ID 才能激活服务
    • 对于这种情况,我已经给出了链接。
    • 您好,我们已经浏览了链接,但我们没有在该代码中找到 IAuthenticator 接口。我希望同样需要访问令牌,在服务帐户的情况下我们没有刷新令牌。
    【解决方案2】:

    代码使用Google .net client library

    服务帐号:

    string[] scopes = new string[] {DriveService.Scope.Drive}; // Full access
    
    var keyFilePath = @"c:\file.p12" ;    // Downloaded from https://console.developers.google.com
    var serviceAccountEmail = "xx@developer.gserviceaccount.com";  // found https://console.developers.google.com
    
    //loading the Key file
    var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);
    var credential = new ServiceAccountCredential( new ServiceAccountCredential.Initializer(serviceAccountEmail) {
                                                       Scopes = scopes}.FromCertificate(certificate));
    

    创建驱动服务

    var service = new DriveService(new BaseClientService.Initializer() {HttpClientInitializer = credential,
                                                                                ApplicationName = "Drive API Sample",});
    

    您可以使用files.list 列出驱动器上的所有文件。

    FilesResource.ListRequest request = service.Files.List();
    request.Q = "trashed=false";
    title = 'hello'
    FileList files = request.Execute();
    

    循环虽然返回的项目找到你想要的文件它是一个文件资源你可以将它传递给下面的方法来下载你的文件

    /// <summary>
            /// Download a file
            /// Documentation: https://developers.google.com/drive/v2/reference/files/get
            /// </summary>
            /// <param name="_service">a Valid authenticated DriveService</param>
            /// <param name="_fileResource">File resource of the file to download</param>
            /// <param name="_saveTo">location of where to save the file including the file name to save it as.</param>
            /// <returns></returns>
            public static Boolean downloadFile(DriveService _service, File _fileResource, string _saveTo)
            {
    
                if (!String.IsNullOrEmpty(_fileResource.DownloadUrl))
                {
                    try
                    {
                        var x = _service.HttpClient.GetByteArrayAsync(_fileResource.DownloadUrl );
                        byte[] arrBytes = x.Result;
                        System.IO.File.WriteAllBytes(_saveTo, arrBytes);
                        return true;                  
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("An error occurred: " + e.Message);
                        return false;
                    }
                }
                else
                {
                    // The file doesn't have any content stored on Drive.
                    return false;
                }
            }
    

    Google drive authentication C# 盗取的代码

    【讨论】:

    • 我们是根据您建议我们的代码来完成这一切的,我们不会循环遍历文件,而是在文件上传时将下载 URL 存储在数据库中,而是简单地传递字符串_fileResource.DownloadUrl。其余的都和你建议的完全一样。
    • 很高兴它成功了 :) 看看下载网址我有一个奇怪的回忆,如果有人在驱动器上更新它,它有时会发生变化。
    • 再澄清一点,因为我们使用此代码获取文件 _fileResource = GetFileByID(fileid, service);然后使用此代码获取下载 url _fileResource.DownloadUrl 但不幸的是它返回了 null 值,因此我们将立场从这里更改为已经可用的文件下载 url。
    • 文件文件 = service.Files.Get(fileId).Execute();应该也返回下载链接我觉得奇怪的是它不是。
    • 我可以在我的 Google 云端硬盘帐户中检查什么,或者有什么可以通过服务电子邮件完成的。我已经创建了新的电子邮件和新的服务帐户,我担心谷歌是否有任何限制。
    猜你喜欢
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 2021-04-05
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    相关资源
    最近更新 更多