【问题标题】:Transfer ownership of file uploaded using Google drive API转让使用 Google Drive API 上传的文件的所有权
【发布时间】:2015-01-10 14:51:23
【问题描述】:

Google Drive API 无法转移从 API 本身上传的文件的所有权。

根据 API 文档,需要使用 PUT 来转移所有权。 当我将它与所需的参数一起使用时,它会返回现有的权限。 不会用新的所有者更新它。

如果我使用 POST 和所需的参数,它会抛出“远程服务器返回错误:(400) 错误请求。”

我能够更改未通过 API 上传的文件的所有权。我用于从 API 上传的文件的相同。所有者没有改变。

是错误还是我做错了什么?

-编辑- 如果有人想要使用 API 上传的文件的详细信息和通过 gdocs 创建的文件,我可以。

-EDIT2-

public bool UploadReportToGoogleDrive(Model model, byte[] ReportPDF_ByteArray, string ddlAddFilesFolder = "root", bool doNotify = true)
    {
        bool isErrorOccured = false;

        try
        {
            SingletonLogger.Instance.Info("UploadReportToGoogleDrive - start");
            FileList fileList = new FileList();
            Google.Apis.Drive.v2.Data.File uploadedFile = new Google.Apis.Drive.v2.Data.File();
            Permission writerPermission = new Permission();

            string accessToken = GetAccessToken();
            #region FIND  REPORT FOLDER
            string url = "https://www.googleapis.com/drive/v2/files?"
                + "access_token=" + accessToken
                + "&q=" + HttpUtility.UrlEncode("title='My Reports' and trashed=false and mimeType in 'application/vnd.google-apps.folder'")
                ;

            // Create POST data and convert it to a byte array.
            List<string> _postData = new List<string>();
            string postData = string.Join("", _postData.ToArray());

            try
            {
                WebRequest request = WebRequest.Create(url);
                string responseString = GDriveHelper.GetResponse(request);
                fileList = JsonConvert.DeserializeObject<FileList>(responseString);
                SingletonLogger.Instance.Info("UploadReportToGoogleDrive - folder search success");
            }
            catch (Exception ex)
            {
                SingletonLogger.Instance.Error("UploadReportToGoogleDrive\\FIND  REPORT FOLDER", ex);
                isErrorOccured = true;
            }
            #endregion FIND  REPORT FOLDER

            if (fileList.Items.Count == 0)
            {
                #region CREATE  REPORT FOLDER
                url = "https://www.googleapis.com/drive/v2/files?" + "access_token=" + accessToken;

                // Create POST data and convert it to a byte array.
                _postData = new List<string>();
                _postData.Add("{");
                _postData.Add("\"title\": \"" + "My Reports" + "\",");
                _postData.Add("\"description\": \"Uploaded with Google Drive API\",");
                _postData.Add("\"parents\": [{\"id\":\"" + "root" + "\"}],");
                _postData.Add("\"mimeType\": \"" + "application/vnd.google-apps.folder" + "\"");
                _postData.Add("}");
                postData = string.Join("", _postData.ToArray());

                try
                {
                    WebRequest request = WebRequest.Create(url);

                    byte[] byteArray = Encoding.UTF8.GetBytes(postData);
                    // Set the ContentType property of the WebRequest.
                    request.ContentType = "application/json";
                    // Set the ContentLength property of the WebRequest.
                    request.ContentLength = postData.Length;//byteArray.Length;
                    // Set the Method property of the request to POST.
                    request.Method = "POST";
                    // Get the request stream.
                    Stream dataStream = request.GetRequestStream();
                    // Write the data to the request stream.
                    dataStream.Write(byteArray, 0, byteArray.Length);
                    // Close the Stream object.
                    dataStream.Close();

                    string responseString = GDriveHelper.GetResponse(request);
                    Google.Apis.Drive.v2.Data.File ReportFolder = JsonConvert.DeserializeObject<Google.Apis.Drive.v2.Data.File>(responseString);
                    ;
                    ddlAddFilesFolder = ReportFolder.Id;
                    SingletonLogger.Instance.Info("UploadReportToGoogleDrive - folder creation success");
                }
                catch (Exception ex)
                {
                    SingletonLogger.Instance.Error("UploadReportToGoogleDrive\\CREATE  REPORT FOLDER", ex);
                    isErrorOccured = true;
                }
                #endregion CREATE  REPORT FOLDER
            }
            else
            {
                ddlAddFilesFolder = fileList.Items.FirstOrDefault().Id;
            }

            if (!isErrorOccured)
            {
                #region UPLOAD NEW FILE - STACKOVER FLOW
                //Createing the MetaData to send
                _postData = new List<string>();

                _postData.Add("{");
                _postData.Add("\"title\": \"" + "Report_" + model.id + "\",");
                _postData.Add("\"description\": \"" + " report of person - " + (model.borrowerDetails.firstName + " " + model.borrowerDetails.lastName) + "\",");

                _postData.Add("\"parents\": [{\"id\":\"" + ddlAddFilesFolder + "\"}],");
                _postData.Add("\"extension\": \"" + "pdf" + "\",");
                _postData.Add("\"appDataContents\": \"" + true + "\",");
                _postData.Add("\"mimeType\": \"" + GDriveHelper.GetMimeType("Report.pdf").ToString() + "\"");
                _postData.Add("}");

                postData = string.Join(" ", _postData.ToArray());
                byte[] MetaDataByteArray = Encoding.UTF8.GetBytes(postData);

                //// creating the Data For the file
                //MemoryStream target = new MemoryStream();
                //myFile.InputStream.Position = 0;
                //myFile.InputStream.CopyTo(target);
                //byte[] FileByteArray = target.ToArray();

                string boundry = "foo_bar_baz";
                url = "https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart" + "&access_token=" + accessToken;

                WebRequest request = WebRequest.Create(url);
                request.Method = "POST";
                request.ContentType = "multipart/related; boundary=\"" + boundry + "\"";

                // Wrighting Meta Data
                string headerJson = string.Format("--{0}\r\nContent-Type: {1}\r\n\r\n",
                                boundry,
                                "application/json; charset=UTF-8");
                string headerFile = string.Format("\r\n--{0}\r\nContent-Type: {1}\r\n\r\n",
                                boundry,
                                GDriveHelper.GetMimeType("Report.pdf").ToString());

                string footer = "\r\n--" + boundry + "--\r\n";

                int headerLenght = headerJson.Length + headerFile.Length + footer.Length;
                request.ContentLength = MetaDataByteArray.Length + ReportPDF_ByteArray.Length + headerLenght;
                Stream dataStream = request.GetRequestStream();
                dataStream.Write(Encoding.UTF8.GetBytes(headerJson), 0, Encoding.UTF8.GetByteCount(headerJson));   // write the MetaData ContentType
                dataStream.Write(MetaDataByteArray, 0, MetaDataByteArray.Length);                                          // write the MetaData


                dataStream.Write(Encoding.UTF8.GetBytes(headerFile), 0, Encoding.UTF8.GetByteCount(headerFile));   // write the File ContentType
                dataStream.Write(ReportPDF_ByteArray, 0, ReportPDF_ByteArray.Length);                                  // write the file

                // Add the end of the request.  Start with a newline

                dataStream.Write(Encoding.UTF8.GetBytes(footer), 0, Encoding.UTF8.GetByteCount(footer));
                dataStream.Close();

                try
                {
                    WebResponse response = request.GetResponse();
                    // Get the stream containing content returned by the server.
                    dataStream = response.GetResponseStream();
                    // Open the stream using a StreamReader for easy access.
                    StreamReader reader = new StreamReader(dataStream);
                    // Read the content.
                    string responseFromServer = reader.ReadToEnd();
                    // Display the content.
                    //Console.WriteLine(responseFromServer);
                    uploadedFile = JsonConvert.DeserializeObject<Google.Apis.Drive.v2.Data.File>(responseFromServer);

                    // Clean up the streams.
                    reader.Close();
                    dataStream.Close();
                    response.Close();

                    SingletonLogger.Instance.Info("UploadReportToGoogleDrive - upload to folder success");
                }
                catch (Exception ex)
                {
                    SingletonLogger.Instance.Error("UploadReportToGoogleDrive\\CREATE REPORT FOLDER", ex);
                    isErrorOccured = true;
                    //return "Exception uploading file: uploading file." + ex.Message;
                }
                #endregion UPLOAD NEW FILE - STACKOVER FLOW
            }

            if (!isErrorOccured)
            {
                #region MAKE ADMIN ACCOUNT OWNER OF UPLOADED FILE - COMMENTED
                url = "https://www.googleapis.com/drive/v2/files/" + uploadedFile.Id
                    + "/permissions/"
                    + uploadedFile.Owners[0].PermissionId
                    + "?access_token=" + accessToken
                    + "&sendNotificationEmails=" + (doNotify ? "true" : "false")
                    ;

                WebRequest request = WebRequest.Create(url);

                string role = "owner", type = "user", value = "aniketpatil87@gmail.com";

                // Create POST data and convert it to a byte array.
                postData = "{"
                + "\"role\":\"" + role + "\""
                + ",\"type\": \"" + type + "\""
                + ",\"value\": \"" + value + "\""
                + ",\"permissionId\":\"" + uploadedFile.Owners[0].PermissionId + "\""
                + ",\"transferOwnership\": \"" + "true" + "\""
                + "}";

                byte[] byteArray = Encoding.UTF8.GetBytes(postData);
                // Set the ContentType property of the WebRequest.
                request.ContentType = "application/json";
                // Set the ContentLength property of the WebRequest.
                request.ContentLength = postData.Length;//byteArray.Length;
                // Set the Method property of the request to POST.
                request.Method = "POST";
                // Get the request stream.
                Stream dataStream = request.GetRequestStream();
                // Write the data to the request stream.
                dataStream.Write(byteArray, 0, byteArray.Length);
                // Close the Stream object.
                dataStream.Close();

                //TRY CATCH - IF TOKEN IS INVALID
                try
                {
                    string responseString = GDriveHelper.GetResponse(request);
                    SingletonLogger.Instance.Info("UploadReportToGoogleDrive - make admin account owner success");
                }
                catch (Exception ex)
                {
                    SingletonLogger.Instance.Error("UploadReportToGoogleDrive\\MAKE ADMIN ACCOUNT OWNER OF UPLOADED FILE", ex);
                    isErrorOccured = true;
                }
                #endregion MAKE ADMIN ACCOUNT OWNER OF UPLOADED FILE

if (model.Officer != default(int))
                    {
                        #region ALLOW OFFICER TO ACCESS UPLOADED FILE
                        OldModels.MWUsers officer = usersBL.GetAll(model.Officer).FirstOrDefault();

                    url = "https://www.googleapis.com/drive/v2/files/" + uploadedFile.Id
                        + "/permissions/"
                        //+ uploadedFile.Owners[0].PermissionId
                    + "?access_token=" + accessToken
                    + "&sendNotificationEmails=" + (doNotify ? "true" : "false")
                    ;

                    request = WebRequest.Create(url);

                    role = "writer";
                    type = "user";
                    value = Officer.EMail;

                    // Create POST data and convert it to a byte array.
                    postData = "{"
                    + "\"role\":\"" + role + "\""
                    + ",\"type\": \"" + type + "\""
                    + ",\"value\": \"" + value + "\""
                        //+ ",\"permissionId\":\"" + uploadedFile.Owners[0].PermissionId + "\""
                        //+ ",\"transferOwnership\": \"" + "true" + "\""
                    + "}";

                    byteArray = Encoding.UTF8.GetBytes(postData);
                    // Set the ContentType property of the WebRequest.
                    request.ContentType = "application/json";
                    // Set the ContentLength property of the WebRequest.
                    request.ContentLength = postData.Length;//byteArray.Length;
                    // Set the Method property of the request to POST.
                    request.Method = "POST";
                    // Get the request stream.
                    dataStream = request.GetRequestStream();
                    // Write the data to the request stream.
                    dataStream.Write(byteArray, 0, byteArray.Length);
                    // Close the Stream object.
                    dataStream.Close();

                    //TRY CATCH - IF TOKEN IS INVALID
                    try
                    {
                        string responseString = GDriveHelper.GetResponse(request);
                        SingletonLogger.Instance.Info("UploadReportToGoogleDrive - make officer writer success");
                    }
                    catch (Exception ex)
                    {
                        SingletonLogger.Instance.Error("UploadReportToGoogleDrive\\ALLOW OFFICER TO ACCESS UPLOADED FILE", ex);
                        isErrorOccured = true;
                    }
                    #endregion ALLOW OFFICER TO ACCESS UPLOADED FILE
                }                    
            }

            if (isErrorOccured)
            {
                SingletonLogger.Instance.Info("UploadReportToGoogleDrive -  report upload to gdrive failed");
            }
            else
            {
                //LogHelper.CreateLogEntry(UserContext.CurrentUser.UserID, "Uploaded " + myFileList.Count + " file(s) on Google Drive.", this.HttpContext.Request);

                SingletonLogger.Instance.Info("UploadReportToGoogleDrive -  report upload to gdrive success");
            }
        }
        catch (Exception ex)
        {
            SingletonLogger.Instance.Info("UploadReportToGoogleDrive - Outer exception", ex);
            isErrorOccured = true;
        }

        return isErrorOccured;

}

【问题讨论】:

  • 能否包含用于更改权限的代码的 sn-p?
  • 我已经用整个代码更新了原帖
  • 你解决过这个问题吗?遇到了同样的问题,我没有使用 Google Apps for Work,因此无法模拟或使用管理工具。你可以看到它发生在:https://developers.google.com/drive/v2/reference/permissions/update with fileId = a file's Id - 尝试通过 Google Drive Windows 应用创建的文件,permissionId = from developers.google.com/drive/v2/reference/permissions/…,transferOwnership = true,请求正文:role = owner
  • @JamesCarlyle-Clarke 抱歉回复晚了。我没有找到解决方案。虽然当我转移在 GDrive 本身上创建或通过其 UI 上传的文件的所有权时,我上面的代码显然有效
  • 有人解决了吗? 5年后问题仍然存在stackoverflow.com/questions/62699404/…

标签: google-drive-api


【解决方案1】:

不确定您是否查看了 PATCH 命令的权限。带有适当参数的 PATCH 命令可以让您转移所有权。

Link to Google Drive API documentation

【讨论】:

  • 感谢您的信息,我尝试使用 Patch。没有错误,但文件的所有权没有改变。
  • 你能分享你为做补丁而写的代码吗?我们使用来自 javascript 的 patch 命令,它工作得很好......所以可能是提供的参数有问题?
【解决方案2】:

您似乎在帖子正文中指定了transferOwnership,但必须根据文档将其指定为 URL 参数。

【讨论】:

  • 感谢您的回复,当我使用在 GDrive 本身上创建的文件或通过其 UI 上传的文件时,此代码有效
  • 我怀疑这会有所作为,但这是可能的。尝试修复代码以将参数移动到正确的位置,看看是否有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
  • 2022-01-04
  • 2017-08-04
  • 2015-01-06
  • 1970-01-01
  • 2015-11-27
  • 1970-01-01
相关资源
最近更新 更多