为什么我的 UpdateFile 在使用 C# 的 google Drive api v3 中的响应中得到空值?

2023-11-21

我有一个用 C# 编写的应用程序,因此它可以是一个独立的 .exe,并在运行时通过 cmd 传入参数。我正在尝试更新 google 驱动器中的文件而不更改 fileid,以便使用该 id 的任何链接都不会被破坏。以下代码一直有效,直到使用 Google.Apis.Drive.v3.Data.File updateFile 到达第三部分,其中文件始终为“null”。 request.ResponseBody 具有正确的 fileId、正确的路径,并且几乎总是出现空值。

我怎样才能得到它来更新文件?

是否有一些代码更新/更改不再有效?

任何帮助,将不胜感激-

第 1 部分 - 这是调用接下来两部分的代码的开头:

    // System Library Requirements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Security;
// Microsoft Library Requirements
using Microsoft.Win32;
// Google API Library Requirements
using Google.Apis.Gmail.v1;
using Google.Apis.Gmail.v1.Data;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using GoogleV2 = Google.Apis.Drive.v2;
using Google.Apis.Drive.v3.Data;

using GoogleV2data = Google.Apis.Drive.v2.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using Google.Apis.Requests;
using Google.Apis.Auth.OAuth2.Responses;
using Google.Api.Gax;
using Google.Cloud.Channel.V1;
// JSON reading/serializing/De-serializing Library Requirements
using Newtonsoft.Json;
// Mime-Type Library Requirements
using MimeKit;
using Google.Apis.Upload;
// CyberArk Library Requirements
using CyberArk.AIM.NetPasswordSDK;
using CyberArk.AIM.NetPasswordSDK.Exceptions;



static class Globals
{
    //cyberark values will change based on the domain and the app and the safe
    public static string google_client_secret;
    public static string cyberark_client_id = "...xxxx.....apps.googleusercontent.com";
    public static string cyberark_object = "...xxx...";
    public static string cyberark_app_id = "...xxx...";
    public static string cyberark_safe = "...xxx...";
    //google app values will change based on the domain and gcp project information e.g. np vs prod
    public static string google_app_name = "my_google_app_name";
    public static string google_client_id = "my_google_client_id";
    public static string google_data_store = "my_google_data_store";

    

}

class Program
{
    static void Main(string[] args)
    {


        Globals.google_client_secret = NetPasswordSDK.CyberArkProgram.GetMyPassword(NetPasswordSDK.MyCredentials.MY_APP_ID, NetPasswordSDK.MyCredentials.MY_SAFE, NetPasswordSDK.MyCredentials.MY_OBJECT, NetPasswordSDK.MyCredentials.MY_SECURE_STRING);

        var paramFolderID = "";
        var paramDriveFromFolderName = "";
        var paramUserID = "";
        var paramTeamID = "";
        var paramFileName = "";
        var paramFilePath = "";
        var paramLocalFolderPath = "";


        if (args == null || args.Length == 0)
        {
            Console.WriteLine("No Arguments passed");
        }
        else
        {
            paramFolderID = args[0];
            paramDriveFromFolderName = args[1];
            paramUserID = args[2];
            paramTeamID = args[3];
            paramFileName = args[4];
            paramFilePath = args[5];
            paramLocalFolderPath = args[6];



            Console.WriteLine("FolderID " + args[0]);
            Console.WriteLine("DriveFromFolderName " + args[1]);
            Console.WriteLine("UserID " + args[2]);
            Console.WriteLine("TeamID " + args[3]);
            Console.WriteLine("FileName " + args[4]);
            Console.WriteLine("FilePath " + args[5]);
            Console.WriteLine("LocalFolderPath " + args[6]);

        }

        string googleUpdateText = "";
        string googleUpdateFilePath = "";
        string googleUpdateLocalFolderPath = "";
        string googleUpdateFileName = "";
        string googleUpdateParentFolder = "";
        string googleUpdateTeamDriveID = "";
        string googleUpdateParentFolderID = "";


        var proxy = WebRequest.DefaultWebProxy;
        proxy.Credentials = CredentialCache.DefaultCredentials;
        var httpClientHandler = new HttpClientHandler()
        {
            Proxy = proxy
        };


        {


            {



                //googleUpdateParentFolderID = paramFolderID;
                //googleUpdateParentFolder = paramDriveFromFolderName;
                //googleUpdateTeamDriveID = paramTeamID;
                //googleUpdateFileName = paramFileName;
                //googleUpdateFilePath = paramFilePath;
                //googleUpdateLocalFolderPath = paramLocalFolderPath;

                // HC values for testing
                googleUpdateFilePath = "C:\\Path\\to_update_file\\update_file.txt";
                googleUpdateLocalFolderPath = "C:\\Path\\to_update_file\\";
                googleUpdateFileName = "update_file.txt";
                googleUpdateParentFolder = "Folder_on_Google_Drive";
                googleUpdateTeamDriveID = "Team_Drive_ID";
                googleUpdateParentFolderID = "Parent_Folder_ID";


                Console.WriteLine("value of   googleUploadFilePath: " + googleUpdateFilePath);
                Console.WriteLine("value of   googleUploadLocalFolderPath: " + googleUpdateLocalFolderPath);
                Console.WriteLine("value of   googleUploadFileName: " + googleUpdateFileName);
                Console.WriteLine("value of   googleUploadParentFolder: " + googleUpdateParentFolder);
                Console.WriteLine("value of   googleUploadTeamDriveID: " + googleUpdateTeamDriveID);
                Console.WriteLine("value of   googleUploadParentFolderID: " + googleUpdateParentFolderID);

                googleUpdateText = (JsonConvert.SerializeObject(GoogleAPI.GoogleAPI_Drive.GDrive_Update_File(googleUpdateFilePath, googleUpdateLocalFolderPath, googleUpdateFileName, "no description", googleUpdateParentFolder, paramUserID, "", "", googleUpdateTeamDriveID, googleUpdateParentFolderID), Formatting.Indented));

                Console.WriteLine("value of googleUpdateText: " + googleUpdateText);
                Console.WriteLine("this is the end of the update text");


                


            };


            // end 
        }

        // end of Main
    }

    // end of program class
}

第 2 部分 - 这是更新文件列表中的文件的代码的中间部分,该列表调用每个文件来更新它。

public static String GDrive_Update_File(string pathToFile, string localFilePath, string fileName, string description, string parentFolder = "", string userid = "", string sharedUserIds = "", string sharerole = "", string teamID = "", string parentFolderID = "")
{



    FileResponseJSON fileJson = new FileResponseJSON();

    List<string> fileArray = new List<string> { };
    IList<FileResponseJSON> filesJSON = new List<FileResponseJSON>();
    IList<Google.Apis.Drive.v3.Data.File> files = new List<Google.Apis.Drive.v3.Data.File>();


    List<string> parents = new List<String> { };
    List<string> kids = new List<String> { };

    UserCredential credential = GoogleAPI_Functions.GetCredentials(userid);
    var service = new DriveService(new BaseClientService.Initializer
    {
        ApplicationName = APP_NAME,
        HttpClientInitializer = credential,
    });

    if (!String.IsNullOrEmpty(parentFolder))
    {
        FilesResource.ListRequest listRequest = service.Files.List();
        listRequest.Q = String.Format("(name contains '{0}') and (mimeType = 'application/vnd.google-apps.folder')", parentFolder);
        listRequest.Fields = "files(*)";


        if (teamID.Length > 3)
        {
            listRequest.SupportsTeamDrives = true;  // new 
            listRequest.Corpora = "teamDrive";  // new 
            listRequest.IncludeTeamDriveItems = true;//new
            listRequest.TeamDriveId = teamID;//new




        }

        // List files.
        IList<Google.Apis.Drive.v3.Data.File> folders = listRequest.Execute().Files;


        foreach (var fldr in folders)
        {


            if (parentFolderID.Length > 3)
            {
                if (fldr.Id.Equals(parentFolderID))
                {
                    parents.Add(fldr.Id);


                }
            }
            else
            {
                parents.Add(fldr.Id);

            }

            Console.WriteLine("value of fldr.Id " + fldr.Id);
        }


    }

    // Upload File MetaData

    // mimeType is important and so it the 'trashed' true/false or it won't be found
    FilesResource.ListRequest fileRequest = service.Files.List();
    string query = "name contains 'update_file.txt' and (mimeType = 'text/plain') and trashed = false";
    fileRequest.Q = String.Format(query);
    fileRequest.Fields = "files(*)";

    fileRequest.SupportsTeamDrives = true;  // new 
    fileRequest.Corpora = "teamDrive";  // new 
    fileRequest.IncludeTeamDriveItems = true;//new
    fileRequest.TeamDriveId = teamID;//new

    IList<Google.Apis.Drive.v3.Data.File> myFiles = fileRequest.Execute().Files;

    Console.WriteLine("Files:");
    if (myFiles != null && myFiles.Count > 0)
    {
        foreach (var myf in myFiles)
        {
            myf.Name = localFilePath + myf.Name;

            Console.WriteLine("{0} ({1})", myf.Name, myf.Id);
            UpdateFile(service, myf.Name, myf.Id);
        }
    }
    else
    {
        Console.WriteLine("No files found.");
    }
    Console.Read();


    var UpdatedID = "";




    return UpdatedID;
}

第 3 节 - 本节应该更新每个文件 --> 这是有问题的部分(Google.Apis.Drive.v3.Data.File UpdatedFile 始终返回 null)

        public static Google.Apis.Drive.v3.Data.File UpdateFile(DriveService _service, string _uploadFile, string _fileId)
    {
        
        Google.Apis.Drive.v3.Data.File file = new Google.Apis.Drive.v3.Data.File();
        byte[] byteArray = System.IO.File.ReadAllBytes(_uploadFile);
        System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
        FilesResource.UpdateMediaUpload request = _service.Files.Update(file, _fileId, stream, GetMimeType(_uploadFile));

        void Upload_ProgressChanged(IUploadProgress progress) =>
        Console.WriteLine(progress.Status + " " + progress.BytesSent);

        void Upload_ResponseReceived(Google.Apis.Drive.v3.Data.File myfile) =>
        Console.WriteLine(myfile.Name + " was uploaded successfully");

        request.ProgressChanged += Upload_ProgressChanged;
        request.ResponseReceived += Upload_ResponseReceived;

        request.Upload();
        Google.Apis.Drive.v3.Data.File updatedFile = request.ResponseBody;
        return updatedFile;



    }

更新:我使用 IUploadProgress.Exception 并收到以下错误 -

Exception: The service drive has thrown an exception: Google.GoogleApiException: Google.Apis.Requests.RequestError
File not found: 1XYZ..... [404]
Errors [
        Message[File not found: 1XYZ.......] Location[fileId - parameter] Reason[notFound] Domain[global]
]
   at Google.Apis.Upload.ResumableUpload.<HandleResponse>d__78.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Google.Apis.Upload.ResumableUpload.<SendNextChunkAsync>d__77.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Google.Apis.Upload.ResumableUpload.<UploadCoreAsync>d__74.MoveNext() 0

再次更新,我能够看到正在生成的 uri 并将其复制/粘贴到浏览器中,当我这样做时,我得到了 405 Method Not allowed;另外,当我尝试不使用 https 并仅使用 http 时,我得到了 403 Forbidden,并且需要 SSL 才能执行此操作

这是没有 ids 的 uri

更新: 在此过程中,api 会生成这两个 url,它们都可以工作并允许我访问

网页内容链接

"https://drive.google.com/uc?id=[docID]&export=download"

网页浏览链接

"https://drive.google.com/file/d/[docID]/view?usp=drivesdk"

最新更新应用了 DalmTo 的修复,但收到新错误 -

// - removed // Google.Apis.Drive.v3.Data.File file = new 

// - added //

            var fileMetadata = new Google.Apis.Drive.v3.Data.File()
            {
                Id = _fileId
            };

            var fsSource = new MemoryStream(Encoding.UTF8.GetBytes(_uploadFile ?? ""));

            var request = _service.Files.Update(fileMetadata, fileMetadata.Id, fsSource, GetMimeType(_uploadFile));

新错误:

Exception: The service drive has thrown an exception: Google.GoogleApiException: Google.Apis.Requests.RequestError
The resource body includes fields which are not directly writable. [403]
Errors [
        Message[The resource body includes fields which are not directly writable.] Location[ - ] Reason[fieldNotWritable] Domain[global]
]

不知道什么会导致这种情况。


文件 ID 是可写的,因此您应该能够将其与请求中的文件元数据一起发送。

var fileMetadata  = new Google.Apis.Drive.v3.Data.File()
{
    Id = "xxx" 
};

var fsSource = new MemoryStream(Encoding.UTF8.GetBytes(uploadString ?? ""));
var  request = service.Files.Update(fileMetadata, fileMetadata.Id , fsSource, GetMimeType(uploadFilePath));

Update

根据评论,您将随您的请求发送一个空的元数据文件对象。

Google.Apis.Drive.v3.Data.File file = new Google.Apis.Drive.v3.Data.File();

Drive 总是会给你一个新的文件 ID。我将原始文件 ID 作为元数据的一部分发送到那里,因为它将使用该文件 ID。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我的 UpdateFile 在使用 C# 的 google Drive api v3 中的响应中得到空值? 的相关文章

  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 在结构中使用 typedef 枚举并避免类型混合警告

    我正在使用 C99 我的编译器是 IAR Embedded workbench 但我认为这个问题对于其他一些编译器也有效 我有一个 typedef 枚举 其中包含一些项目 并且我向该新类型的结构添加了一个元素 typedef enum fo
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 链接器错误:已定义

    我尝试在 Microsoft Visual Studio 2012 中编译我的 Visual C 项目 使用 MFC 但出现以下错误 error LNK2005 void cdecl operator new unsigned int 2
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写

随机推荐