Google云端硬盘。上传文件时刷新授权令牌

时间:2012-10-15 14:23:29

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

将大型文件上传到Google云端硬盘时,刷新授权令牌的方法是什么? 例如:当前授权令牌的到期时间是“06:00 AM”。文件上传始于“05:15 AM”。因此,在“06:00 AM”,应用程序获得异常,因为授权令牌无效。

我已尝试使用以下源代码解决此问题,但它不起作用。

/// <summary>
/// Uploads a file with a specified path.
/// </summary>
/// <param name="startFolder">The start folder.</param>
/// <param name="path">The path of destination file.</param>
/// <param name="localFile">The local file to upload.</param>
/// <returns>The uploaded file.</returns>
private File GdUploadFile(File startFolder, string path, FileInfo localFile)
{
    if (startFolder == null)
    {
        throw new ArgumentNullException("startFolder");
    }

    if (localFile == null)
    {
        throw new ArgumentNullException("localFile");
    }

    if (!localFile.Exists)
    {
        throw new FileNotFoundException("File not found", localFile.FullName);
    }

    var config = GetConfiguration();

    if (config.TraceLog)
    {
        Destination.Logger.LogDebug(string.Format("{0} \tUpload file \"{1}\" to \"{2}\"", Destination.Name, localFile.FullName, path));
    }

    string pathToFile = string.IsNullOrEmpty(path) ? localFile.Name : path;

    string remotePath = ExtractFilePath(pathToFile);
    var fileFolder = GdCreateFolderByPath(startFolder, remotePath);
    var fileName = ExtractFileName(pathToFile);

    DriveService service = GetDriveService();

    var body = new File
                   {
                       Title = fileName,
                       Description = "My File",
                       MimeType = BackupFileMimeType,
                       Kind = DriveFileKindType,
                       OriginalFilename = fileName,
                       FileExtension = localFile.Extension,
                       Parents = new List<ParentReference>
                                     {
                                         new ParentReference
                                             {
                                                 ETag = fileFolder.ETag,
                                                 Id = fileFolder.Id,
                                                 Kind = fileFolder.Kind
                                             }
                                     }
                   };

    FilesResource.InsertMediaUpload request;
    var source = new MediaFileSource(localFile.FullName, BackupFileMimeType);

    using (var fileStream = source.GetDataStream())
    {
        if (config.TraceLog)
        {
            Destination.Logger.LogDebug(string.Format("{0} \tUploading \"{1}\"...", Destination.Name, localFile.FullName));
        }

        request = service.Files.Insert(body, fileStream, body.MimeType);

        if (config.TraceLog)
        {
            int postedPercent = 0;

            request.ProgressChanged += p =>
                                           {
                                               var currentPercent = (int) (p.BytesSent/(double) source.ContentLength*100);

                                               if (currentPercent != postedPercent)
                                               {
                                                   string msg = string.Format("{0} \tPosted {1}% ({2} bytes)", Destination.Name,
                                                                              currentPercent, p.BytesSent);
                                                   Destination.Logger.LogDebug(msg);
                                                   postedPercent = currentPercent;
                                               }
                                           };
        }

        var connection = Destination.Connection as GoogleDriveDestinationConnection;
        Debug.Assert(connection != null, "connection != null");

        request.ProgressChanged += p =>
                                       {
                                           bool refreshAuth = connection.ForceRefreshAuthorization();
                                           var auth =
                                               request.Authenticator as
                                               Google.Apis.Authentication.OAuth2.OAuth2Authenticator<NativeApplicationClient>;

                                           if (auth != null && auth.State != null && refreshAuth)
                                           {
                                               var state = connection.AuthorizationState;
                                               auth.State.AccessToken = state.AccessToken;
                                               auth.State.AccessTokenExpirationUtc = state.AccessTokenExpirationUtc;
                                               auth.State.AccessTokenIssueDateUtc = state.AccessTokenIssueDateUtc;
                                               auth.State.Callback = state.Callback;
                                               auth.State.RefreshToken = state.RefreshToken;
                                               auth.State.SaveChanges();

                                               if (config.TraceLog)
                                               {
                                                   Destination.Logger.LogDebug("Authorization state for the upload request is updated");
                                               }

                                           }
                                       };

        request.ChunkSize = ChunkSize;
        request.Upload();

        if (config.TraceLog)
        {
            Destination.Logger.LogDebug(string.Format("{0} \t\"{1}\" uploaded", Destination.Name, localFile.FullName));
        }
    }

    return request.ResponseBody;
}

2 个答案:

答案 0 :(得分:1)

考虑进行可恢复上传(https://developers.google.com/drive/manage-uploads#resumable)。需要时刷新令牌,并在上次停止的位置继续上传。

答案 1 :(得分:0)

我无法找到无效授权令牌问题的满意解决方案。 所以我创建了自己的开源轻量级库,用于处理Google云端硬盘上的文件。该库直接调用所有REST函数,并完全控制上载或下载过程。它通过每小时刷新授权令牌来解决问题。该库目前在我公司的Sql Server备份产品的数千个安装中使用,它非常稳定并且已经成功解决了这个问题。您可以从此处获取源代码和示例:https://github.com/AlexeyVlg/Pranas.Net.Clouds

相关问题