首页 > 解决方案 > 在使用 Google Drive .NET API 上传文件时,有时会出现 Null ResponseBody

问题描述

当我将一些文件发送到谷歌驱动器时,我有时会得到空的 ResponseBody。

这是随机发生的,大多数文件都已发送,但十分之一的文件返回 null ResponseBody。

我搜索了这个,但只有关于 aways 得到 response null herehere的问题

我的代码:

await UploadFileAsync(...); //exception here

public Task<string> UploadFileAsync(DriveService driveService, string LocalPath, string gdriveFileName, string GDriveFolder, IProgress<long> progress)
{
            return Task.Run(() =>
            {
                var folderId = GetDirectoryOrCreateIfNotExist(driveService, GDriveFolder);
                var file = CreateGDriveFile(gdriveFileName, folderId);

                IUploadProgress result = null;
                FilesResource.CreateMediaUpload request;
                using (var stream = new System.IO.FileStream(LocalPath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                {
                    request = driveService.Files.Create(file, stream, "image/jpeg");
                    request.ChunkSize = ResumableUpload.MinimumChunkSize * 4;

                    request.ProgressChanged += (p) => progress.Report(p.BytesSent * 100 / stream.Length);

                    request.Fields = "id, webContentLink, name";
                    result = request.Upload();
                }

                if (request == null)
                    throw new Exception("O request é nulo");

                if (request.ResponseBody == null)
                    throw new Exception("O ResponseBody é nulo"); //Throw here sometimes

                var fileUploaded = request.ResponseBody;

                return fileUploaded.WebContentLink;
            });
}

private string GetDirectoryOrCreateIfNotExist(DriveService driveService, string folderName)
        {
            var folder = GetFolderIdByName(driveService, folderName).FirstOrDefault();

            if (folder == null)
            {
                folder = CreateGDriveDirectory(driveService, folderName);
                AplyPermissionToFile(driveService, folder);
            }

            return folder;
        }

private File CreateGDriveFile(string fileName, string folderName = null)
        {
            var file = new File()
            {
                Name = fileName
            };

            if (folderName != null)
            {
                file.Parents = new List<string>
                {
                    folderName
                };
            }

            return file;
        }

为什么 ResponseBody 为空?为什么这种情况只发生几次?

更新:

我编辑 UploadFileAsync(),检查 UploadStatus,现在我得到:

The service drive has thrown an exception: Google.GoogleApiException: Google.Apis.Requests.RequestError
Internal Error [500]
Errors [
    Message[Internal Error] Location[ - ] Reason[internalError] Domain[global]
]

更新的代码:(见 result.Status != U​​ploadStatus.Completed)

public Task<string> UploadFileAsync(DriveService driveService, string LocalPath, string gdriveFileName, string GDriveFolder, IProgress<long> progress)
        {
            return Task.Run(() =>
            {
                var folderId = GetDirectoryOrCreateIfNotExist(driveService, GDriveFolder);
                var file = CreateGDriveFile(gdriveFileName, folderId);

                IUploadProgress result = null;
                FilesResource.CreateMediaUpload request;
                using (var stream = new System.IO.FileStream(LocalPath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                {
                    request = driveService.Files.Create(file, stream, "image/jpeg");
                    request.ChunkSize = ResumableUpload.MinimumChunkSize * 4;

                    request.ProgressChanged += (p) => progress.Report(p.BytesSent * 100 / stream.Length);

                    request.Fields = "id, webContentLink, name";
                    result = request.Upload();
                }

                if (result.Status != UploadStatus.Completed) //check status, now it's throwing here sometimes
                    throw result.Exception;

                if (request == null)
                    throw new Exception("O request é nulo");

                if (request.ResponseBody == null)
                    throw new Exception("O ResponseBody é nulo");

                var fileUploaded = request.ResponseBody;

                return fileUploaded.WebContentLink;
            });
        }

有人能帮我吗?

标签: c#.netgoogle-drive-apigoogle-api-dotnet-client

解决方案


您收到500 错误代码,因为这是与指数退避相关的问题。由于您尝试发出的并发请求的数量,它会发生。

因此,在您的代码中,您需要应用一些逻辑来避免该问题。例如这个算法

如果请求失败,请等待 1 + random_number_milliseconds 秒,然后重试请求。

如果请求失败,请等待 2 + random_number_milliseconds 秒,然后重试请求。

如果请求失败,请等待 4 + random_number_milliseconds 秒,然后重试请求。

依此类推,直到maximum_backoff 时间。

在哪里:

等待时间为 min(((2^n)+random_number_milliseconds), maximum_backoff),每次迭代(请求)时 n 递增 1。

random_number_milliseconds 是小于或等于 1000 的随机毫秒数。这有助于避免许多客户端在某些情况下同步并一次重试,以同步波发送请求的情况。每次重试请求后都会重新计算 random_number_milliseconds 的值。

maximum_backoff 通常为 32 或 64 秒。适当的值取决于用例。


推荐阅读