无法使用服务帐户向Google Drive插入文件

本文关键字:Google Drive 插入 文件 服务 | 更新日期: 2023-09-27 18:11:34

我无法使用服务帐户插入谷歌驱动器。相反,我可以用相同的服务帐户从google drive下载和更新文件,而不会出现任何问题。我从一个特定的用户(我们称之为用户"X")帐户中创建了服务帐户,通过从谷歌开发者控制台进入[我的项目]->"API和Auth"->"凭据"->"创建新的客户端ID"。

然后,我专门为用户"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中的错误,还是我错过了样本中未包含的东西?

请记住,我已经给了服务帐户编辑访问我要上传的文件夹的权限,所以这应该不是问题。我没有试图冒充用户,也不认为在这种情况下我需要这样做。

提前感谢您的帮助!

UPDATE:我尝试创建一个InstalledApplication而不是ServiceAccount。我能够很好地验证安装的应用程序(对于用户"X")并获得我的访问权限& &;刷新令牌,但我得到了这个完全相同的错误在这个相同的上下文中!

无法使用服务帐户向Google Drive插入文件

似乎问题是与"BufferedWriteToTarget"方法,但我不知道为什么它会导致一个问题?一旦我改变使用"ReadAllBytes"方法,如示例所示,它工作得很好。

下面是我为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);
    }

我打算保留这篇文章,因为我认为它提供了关于我设置服务帐户的步骤的信息。