无法使用服务帐户将文件插入Google云端硬盘

时间:2014-07-03 19:45:48

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

我无法使用服务帐户插入谷歌驱动器。相反,我可以使用相同的服务帐户从谷歌驱动器下载和更新文件,没有任何问题。 我通过转到[我的项目] - >从特定用户(让我们称之为用户“X”)帐户创建了服务帐户。 “API和Auth” - > “证书” - >从谷歌开发者控制台“创建新的客户端ID”。

然后我专门访问了MyDrive for User“X”上的文件夹,并将此文件夹与OAuth2的“创建新客户端ID”步骤生成的服务帐户电子邮件地址共享。我确保为此文件夹指定服务帐户权限为“可以编辑”。

我已经成功地从该文件夹下载文件,以及从该文件夹更新文件。我认为这意味着我的服务帐户已经过适当的身份验证(我成功地获得了一个有一个小时的AccessToken)。我已经确定我的范围也是完整的访问范围(即https://www.googleapis.com/auth/drive)。

所有这一切,当我尝试插入新文件时,它失败了。我在这里使用了基本模板:https://developers.google.com/drive/v2/reference/files/insert

以下是插入的代码示例:

using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v2;
using Google.Apis.Util;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Drive.v2.Data;

File body = new File();
body.Title = "Test.pdf";
body.Description = "Why doesn't this work?";
body.MimeType = "application/pdf";
body.Parents = new List<ParentReference>() { new ParentReference() { Id = [ID GOES HERE] } };
using (System.IO.MemoryStream oMemoryStream = new System.IO.MemoryStream())
        {
            string sUploadFileFromDiskPath = @"[PATH TO FILE]";
            using (System.IO.FileStream oFileStream = System.IO.File.OpenRead(sUploadFileFromDiskPath))
            {
                this.BufferedWriteToTarget(oFileStream, oMemoryStream);
                oFileStream.Close();
            }
            FilesResource.InsertMediaUpload insertRequest = ServiceAccount.DriveService.Files.Insert(body, oMemoryStream, body.MimeType); //NOTE: "DriveService" is authenticated (has an AccessToken from the ServiceAccountCredential) in this context with full scope authority
            IUploadProgress progress = insertRequest.Upload();
            File file = insertRequest.ResponseBody; //This is "null" prior to execution because the .Upload() threw an exception
            oMemoryStream.Close();
        }

在Upload()调用上遇到异常,我可以在IUploadProgress对象中看到这个异常。例外情况是 “未找到给定的标题” 。堆栈跟踪如下: " at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)\r\n at Microsoft.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n at Microsoft.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult()\r\n at Google.Apis.Upload.ResumableUpload1.<UploadCoreAsync>d__e.MoveNext() in c:\\code\\google.com\\google-api-dotnet-client\\default\\Tools\\Google.Apis.Release\\bin\\Debug\\output\\default\\Src\\GoogleApis\\Apis\\[Media]\\Upload\\ResumableUpload.cs:line 459"

这是API中的错误,还是我遗漏了样本中未包含的内容?

请注意,我已将服务帐户编辑权限授予我正在尝试上传到的文件夹,因此这应该不是问题。我不是试图冒充用户,也不相信我需要的这种情况。

提前感谢您的帮助!

更新:我尝试创建InstalledApplication而不是ServiceAccount。我能够很好地验证InstalledApplication(对于用户“X”)并获得我的Access&amp;刷新令牌,但我在同样的背景下得到了这个完全相同的错误!

1 个答案:

答案 0 :(得分:1)

问题出现在&#34; BufferedWriteToTarget&#34;方法,但我不确定它为什么会导致问题?一旦我改为使用&#34; ReadAllBytes&#34;方法如示例所示,工作正常。

以下是我对BufferedWriteToTarget的代码:

    private void BufferedWriteToTarget(System.IO.Stream oSourceStream, System.IO.Stream oDestinationStream)
    {
        ////This code copies one stream into another stream.
        const int READ_BUFFER_SIZE = 8192;
        byte[] buffer = new byte[READ_BUFFER_SIZE];
        int n;
        while ((n = oSourceStream.Read(buffer, 0, buffer.Length)) != 0)
            oDestinationStream.Write(buffer, 0, n);
    }

我要保留这个帖子,因为我觉得它在设置服务帐户的步骤方面提供了丰富的信息(例如,我在其他任何地方都没有看到任何文档如何设置具有用户帐户内特定文件夹权限的服务帐户。