“禁止”错误通过API上传到Google云端硬盘

时间:2016-01-17 18:47:19

标签: c# google-drive-api

我一直在使用.NET Google Drive API,我可以通过API成功连接,验证和获取文件列表(我们的Google云端硬盘帐户上已有数千个文件,直接通过幅)。

但是,我在尝试写入数据时遇到两个非常相似的错误:如果我尝试上传测试文件(test.txt),我会收到403“禁止”错误。尝试创建一个新文件夹会给我一个类似的错误:

  

抛出异常:Google.Apis.dll中的“Google.GoogleApiException”

     

其他信息:Google.Apis.Requests.RequestError

     

权限不足[403]位置[ - ]原因[不足权限]域[全局]

我已经按照“快速入门”教程和其他类似的问题,但我看不出还有什么需要做的。这是我上传文件的示例代码;我需要在代码或Google云端硬盘帐户中添加/更改哪些内容才能上传文件和创建文件夹?

 class GDriveTest
{
    static string[] Scopes = { DriveService.Scope.Drive,DriveService.Scope.DriveFile };
    static string ApplicationName = "Drive API .NET Quickstart";

    static void Main(string[] args)
    {
        UserCredential credential;

        using (var stream =
            new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
        {
            string credPath = System.Environment.GetFolderPath(
                System.Environment.SpecialFolder.Personal);
            credPath = Path.Combine(credPath, ".credentials/drive-dotnet-quickstart");

            credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                GoogleClientSecrets.Load(stream).Secrets,
                Scopes,
                "user",
                CancellationToken.None,
                new FileDataStore(credPath, true)).Result;
            Console.WriteLine("Credential file saved to: " + credPath);
        }

        // Create Drive API service.
        var service = new DriveService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = ApplicationName,
        });

        UploadSingleFile(service);
    }

    private static void UploadSingleFile(DriveService service)
    {
        File body = new File();
        body.Title = "My document";
        body.Description = "A test document";
        body.MimeType = "text/plain";

        byte[] byteArray = System.IO.File.ReadAllBytes("test.txt");
        System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);

        FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream, "text/plain");
        request.Upload();

        File file = request.ResponseBody;
        Console.WriteLine("File id: " + file.Id);
        Console.ReadLine();
    }
}

2 个答案:

答案 0 :(得分:1)

问题可能是您要求的范围

DriveService.Scope.DriveFile,   // view and manage files created by this app

尝试

DriveService.Scope.Drive,  // view and manage your files and documents

我的代码:

 /// <summary>
        /// Authenticate to Google Using Oauth2
        /// Documentation https://developers.google.com/accounts/docs/OAuth2
        /// </summary>
        /// <param name="clientId">From Google Developer console https://console.developers.google.com</param>
        /// <param name="clientSecret">From Google Developer console https://console.developers.google.com</param>
        /// <param name="userName">The user to authorize.</param>
        /// <returns>a valid DriveService</returns>
        public static DriveService AuthenticateOauth(string clientId, string clientSecret, string userName)
        {
            if (string.IsNullOrEmpty(clientId))
                throw new Exception("clientId is required.");
            if (string.IsNullOrEmpty(clientSecret))
                throw new Exception("clientSecret is required.");
            if (string.IsNullOrEmpty(userName))
                throw new Exception("userName is required for datastore.");


            string[] scopes = new string[] { DriveService.Scope.Drive};

            try
            {

                string credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                credPath = Path.Combine(credPath, ".credentials/Drive");

                // here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
                UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret }
                                                                                             , scopes
                                                                                             , userName
                                                                                             , CancellationToken.None
                                                                                             , new FileDataStore(credPath, true)).Result;

                var service = new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "Drive Authentication Sample",
                });
                return service;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.InnerException);
                throw ex;
            }

        }

/// <summary>
        /// Insert a new file.
        /// Documentation: https://developers.google.com/drive//v2/files/insert
        /// </summary>
        /// <param name="service">Valid authentcated DriveService</param>
        /// <param name="body">Valid File Body</param>
        /// <returns>File </returns>
        public static File Insert(DriveService service, File body)
        {
            //Note Genrate Argument Exception (https://msdn.microsoft.com/en-us/library/system.argumentexception(loband).aspx)
            try
            {  
            return          service.Files.Insert(body).Execute();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Request Failed " + ex.Message);
                throw ex;
            }
         }

  private static string GetMimeType(string fileName)
        {
            string mimeType = "application/unknown";
            string ext = System.IO.Path.GetExtension(fileName).ToLower();
            Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
            if (regKey != null && regKey.GetValue("Content Type") != null)
                mimeType = regKey.GetValue("Content Type").ToString();
            return mimeType;
        }

执行

var driveService = StandardGoogleAuth.AuthenticateOauth("xxxxx.apps.googleusercontent.com", "uxpj6hx1H2N5BFqdnaNhIbie", "user");

                var uploadfileName = @"C:\Temp\test.txt";
               File body = new File();
                body.Title = System.IO.Path.GetFileName(uploadfileName);
                body.Description = "File uploaded by Diamto Drive Sample";
                body.MimeType =  GetMimeType(uploadfileName);
                body.Parents = new List<ParentReference>() { new ParentReference() { Id = "root" } };

                // File's content.
                byte[] byteArray = System.IO.File.ReadAllBytes(uploadfileName);
                System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);

             var result = FilesSample.Insert(driveService,body);

答案 1 :(得分:0)

修改范围不会自动更新到TOKENRESPONSE用户文件中。您必须重新生成该文件。

搜索“drive-dotnet-quickstart.json”并从其中删除“Google.Apis.Auth.OAuth2.Responses.TokenResponse-user”。 然后运行代码以重新生成该文件。