【问题标题】:Issue with downloading files from gDrive with Google API for .NET使用 Google API for .NET 从 gDrive 下载文件的问题
【发布时间】:2019-03-16 06:28:58
【问题描述】:

几年前我就有一个应用程序,用户可以使用它从 gDrive 加载数据。数据可以来自原生 Google 电子表格 (gSheets) 或 txt、csv、xlsx 等文件。突然,从这周开始有时文件就不能再下载了,尽管我们这边没有任何改变。当我尝试下载文件时,我现在得到一个基本上是登录屏幕的 html 页面的内容。但是gSheets 的内容仍然可以下载,所以这不可能是我使用的服务帐户的一些访问问题。我还可以确认这些文件仍与该服务帐户共享。 我正在使用此代码下载文件:

        String serviceAccountEmail = this.apiConfig.ClientIdEmail;
        Byte[] keyFile = this.apiConfig.FileP12;

        var certificate = new X509Certificate2(keyFile, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

        ServiceAccountCredential credential = new ServiceAccountCredential(
           new ServiceAccountCredential.Initializer(serviceAccountEmail)
           {
               Scopes = new[] { DriveService.Scope.Drive, DriveService.Scope.DriveFile }
           }.FromCertificate(certificate));

        DriveService service = new DriveService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "Drive Spotfire Datasource",
        });

        var response = service.HttpClient.GetByteArrayAsync(exportUrl).Result;
        Stream downloadStream = new MemoryStream(response);

“exportUrl”的格式为

https://docs.google.com/a/<domain.com>/uc?id=<fileId>&export=download&gid=0

当我在浏览器中尝试这个 URL 时,我可以毫无问题地下载文件。 与此同时,我尝试使用来自 NuGet(版本 1.38)的最新 dll,用于 Google.Apis.Drive.v2 和 Google.Apis.Drive.v3。 有谁知道为什么这些下载突然不再工作了?

【问题讨论】:

  • 看起来您正在使用经过服务帐户身份验证的 http 客户端进行直接下载。我知道您说服务帐户仍然具有文件访问权限,但问题的最可能原因是文件的权限已更改,并且服务帐户不再被授权访问文件。这可以解释为什么您看到的是授权 html 页面而不是预期的文件内容。您的exportURL 可以在浏览器中使用,因为您已经在浏览器中登录。
  • 嗨@Chris,感谢您的评论。我在 gDrive 中检查了文件仍与服务帐户共享。他们确实这样做了,就像 gSheets 仍然与它共享一样。事实上,我还使用新的 p12 文件创建了一个新的服务帐户,并与这个新帐户共享 gDrive 中的文件,但同样的问题仍然存在。
  • 刚刚尝试使用 Google.Apis.Drive.v3。还是同样的问题。

标签: c# google-api google-drive-api google-api-dotnet-client


【解决方案1】:

与此同时,我找到了解决方案。原来下载文件时需要使用另一个URL:

    String serviceAccountEmail = this.apiConfig.ClientIdEmail;
    Byte[] keyFile = this.apiConfig.FileP12;

    var certificate = new X509Certificate2(keyFile, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);

    ServiceAccountCredential credential = new ServiceAccountCredential(
       new ServiceAccountCredential.Initializer(serviceAccountEmail)
       {
           Scopes = new[] { DriveService.Scope.Drive, DriveService.Scope.DriveFile }
       }.FromCertificate(certificate));

    DriveService service = new DriveService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = "Drive Spotfire Datasource",
    });

    //get file handler
    Google.Apis.Drive.v2.Data.File file = service.Files.Get(this.uniqueKey).Execute();
    if (!file.MimeType.Equals("application/vnd.google-apps.spreadsheet"))
    {
        //for files use another Url
        exportUrl = file.DownloadUrl;
    }
    var response = service.HttpClient.GetByteArrayAsync(exportUrl).Result;
    Stream downloadStream = new MemoryStream(response);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多