【问题标题】:Google Drive API not uploading file from IISGoogle Drive API 未从 IIS 上传文件
【发布时间】:2015-10-13 08:04:18
【问题描述】:

我正在使用 Google APIs .Net 客户端库通过 Google Drive API 使用服务帐户上传到 Google Drive。当我从 Visual Studio(调试)尝试时,这很好用,甚至当我在本地 IIS 上部署它时也能正常工作。

但是当我在我的服务器(Microsoft Server 2012,IIS 8.5)上部署文件时,文件没有上传,也没有抛出任何异常。这是一段代码:

byte[] byteArray = System.IO.File.ReadAllBytes(uploadFile);
Logger.LoggingService.LogError("GoogleHelper", "Is byteArray null  :" + (byteArray == null)); // Line to check if bytearray is null, I am getting false in log.
Logger.LoggingService.LogError("GoogleHelper", "ByteArray length  :" + byteArray.Length); // Getting actual length here.
System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);

FilesResource.InsertMediaUpload request = DriveService.Files.Insert(body, stream, GetMimeType(uploadFile));
request.Upload();
return request.ResponseBody;

我得到 Null 作为回报。上面的代码在 try 块中,catch 正在记录异常,但没有抛出异常。

我已授予 IIS 用户对此文件夹的完全访问权限。

有人遇到过同样的问题吗?欢迎任何指向解决方案的指针。

更新

它适用于除 Office 文件之外的所有文件。由于 XLSX 等在谷歌驱动器上看起来不正确,我修改了 MIME 类型,如下所示:

Google.Apis.Drive.v2.Data.File body = new Google.Apis.Drive.v2.Data.File();                    
body.Title = System.IO.Path.GetFileName(uploadFile);
body.Description = description;
body.MimeType = GetMimeType(uploadFile, false);
body.Parents = new List<ParentReference>() { new ParentReference() { Id = parent } };
byte[] byteArray = System.IO.File.ReadAllBytes(uploadFile);
System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
FilesResource.InsertMediaUpload request = DriveService.Files.Insert(body, stream, GetMimeType(uploadFile));
request.ResponseReceived += request_ResponseReceived;
request.Upload();
return request.ResponseBody; 

看到我已经调用 GetMimeType 两次 body.MimeType = GetMimeType(uploadFile, false);DriveService.Files.Insert(body, stream, GetMimeType(uploadFile)) 以便文件正确上传到 Google 驱动器,她是我的 GetMimeType 方法:

private string GetMimeType(string fileName, bool ignoreExtension = true)
    {
        string mimeType = "application/unknown";
        string ext = System.IO.Path.GetExtension(fileName).ToLower();

        if (ignoreExtension == false)
        {
            switch (ext)
            {
                case ".ppt":
                case ".pptx":
                    mimeType = "application/vnd.google-apps.presentation";
                    break;
                case ".xls":
                case ".xlsx":
                    mimeType = "application/vnd.google-apps.spreadsheet";
                    break;
                case ".doc":
                case ".docx":
                    mimeType = "application/vnd.google-apps.document";
                    break;
                default:
                    Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
                    if (regKey != null && regKey.GetValue("Content Type") != null)
                        mimeType = regKey.GetValue("Content Type").ToString();
                    break;
            }
        }
        else
        {
            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;
    }

【问题讨论】:

  • 您是否 100% 确定 IIS 有权访问包含您尝试上传的文件的目录?尝试在上面打开一个文件或测试它是否可以访问。
  • 是的@DalmTo 我非常确定它可以访问,即使尝试一下,我也已授予“每个人”的完全访问权限。
  • 你能做一个files.list之类的吗?只是为了检查您是否可以访问 Google,而不是防火墙阻止身份验证服务器问题。
  • 取得了进展,它适用于 PDF、TXT 等,但不适用于 docx、pptx 和 xlsx。我已经更新了问题。
  • daimto.com 的所有链接都在书签中。我只从您的帖子中学习了所有 google api 代码。请看一下GetMimeType,我修改后只能正确查看上传XLSX、PPTX等。有什么办法解决吗?

标签: c# iis google-drive-api google-api-dotnet-client service-accounts


【解决方案1】:

我不确定这是否是问题所在。我没有生产 IIS 服务器,无法对其进行测试。我怀疑问题可能与 mime 类型有关,我不确定它在本地系统而不是您的生产系统上如何工作,但请尝试此代码。如果它不起作用,我可以删除答案。

确保添加

request.Convert = true;

这告诉驱动器将文件转换为驱动器格式,而不仅仅是上传 xls。

代码

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;
        }

        /// <summary>
        /// Uploads a file
        /// Documentation: https://developers.google.com/drive/v2/reference/files/insert
        /// </summary>
        /// <param name="_service">a Valid authenticated DriveService</param>
        /// <param name="_uploadFile">path to the file to upload</param>
        /// <param name="_parent">Collection of parent folders which contain this file. 
        ///                       Setting this field will put the file in all of the provided folders. root folder.</param>
        /// <returns>If upload succeeded returns the File resource of the uploaded file 
        ///          If the upload fails returns null</returns>
        public static File uploadFile(DriveService _service, string _uploadFile, string _parent) {

            if (System.IO.File.Exists(_uploadFile))
            {
                File body = new File();
                body.Title = System.IO.Path.GetFileName(_uploadFile);
                body.Description = "File uploaded by Diamto Drive Sample";
                body.MimeType = GetMimeType(_uploadFile);
                body.Parents = new List<ParentReference>() { new ParentReference() { Id = _parent } };

                // File's content.
                byte[] byteArray = System.IO.File.ReadAllBytes(_uploadFile);
                System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
                try
                {
                    FilesResource.InsertMediaUpload request = _service.Files.Insert(body, stream, GetMimeType(_uploadFile));
                    request.Convert = true;
                    request.Upload();
                    return request.ResponseBody;
                }
                catch (Exception e)
                {
                    Console.WriteLine("An error occurred: " + e.Message);
                    return null;
                }
            }
            else {
                Console.WriteLine("File does not exist: " + _uploadFile);
                return null;
            }           

        }

Google drive sample project 撕下的代码我刚刚添加了转换。

【讨论】:

  • 还是不走运,我看到 docx 等为 ZIP。
  • 检查硬编码解决方案。 stackoverflow.com/questions/58510/… dam 但那很乱。为什么你的服务器返回错误的 mime 类型......(思考)
  • 我认为我们的服务器上没有 word 或 excel,因此它在注册表中不可用。正如这里所说的stackoverflow.com/questions/3442607/…
  • 现在说得通了。尝试更改代码以添加正确的文件 MIME 类型,而不是 Google 的 MIME 类型。
  • 我很高兴我们让它工作了。我想我要编辑示例项目并编写一些硬代码。此问题可能会影响其他人。
猜你喜欢
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-06
相关资源
最近更新 更多