3

I am using Google APIs .Net client library to upload to Google drive though the Google Drive API using a service account. This works well when I try from Visual Studio (debugging) or even works when I deploy it on my local IIS.

But file does not get uploaded when I deploy it on my server (Microsoft Server 2012, IIS 8.5), also does not throw any exception. Here is the piece of code:

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;

I am getting Null in return. Above code is inside try block and catch is logging the exception, but no exception is thrown.

I have given the full access to IIS user to this folder.

Anybody has faced same issue? Any pointer towards solution is welcome.

UPDATE

Its working for all files except the Office files. Since XLSX etc were not looking properly on google drive I had modified the MIME type like following:

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; 

See I have called GetMimeType twice body.MimeType = GetMimeType(uploadFile, false); and DriveService.Files.Insert(body, stream, GetMimeType(uploadFile)) so that file get uploaded on Google drive properly and her is my method 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;
    }
PM.
  • 1,735
  • 1
  • 30
  • 38
  • are you 100% sure that IIS has access to the directory containing the file you are trying to upload? try and just do a file open on it or something to test it has access. – Linda Lawton - DaImTo Jul 23 '15 at 07:13
  • Yes @DalmTo I am very much sure that it has access, even to try out, I have given full access to "everyone". – PM. Jul 23 '15 at 07:18
  • can you do a files.list or something? Just to check you are getting access to Google and its not a firewall blocking authentication server issues. – Linda Lawton - DaImTo Jul 23 '15 at 07:22
  • Yes I am getting the folder id and that folder id is passed as parent for this upload: `body.Parents = new List() { new ParentReference() { Id = parent } };` – PM. Jul 23 '15 at 07:36
  • 1
    Made one progress, its working for PDF,TXT etc but just not working for docx,pptx and xlsx. I have updated the question. – PM. Jul 23 '15 at 07:49
  • did you add convert to the body? Seams weird that it works in dev but not production. wonder if production has an issue with GetMimeType. – Linda Lawton - DaImTo Jul 23 '15 at 07:51
  • added GetMimeType code. @DalmTo are you Linda? – PM. Jul 23 '15 at 08:00
  • Yes, how did you guess :) – Linda Lawton - DaImTo Jul 23 '15 at 08:06
  • mine types are wrong http://www.sitepoint.com/web-foundations/mime-types-summary-list/ You need to send the mime type of the file itself not the one you want to covert it to. Google will figure that out for you. assuming you added convert to the body. – Linda Lawton - DaImTo Jul 23 '15 at 08:08
  • 1
    All links of http://www.daimto.com are in bookmark. I have learnt all google api code from your posts only. Please have a look at GetMimeType, I have modified only to view upload XLSX,PPTX etc properly. Any idea to fix it? – PM. Jul 23 '15 at 08:08

1 Answers1

1

I am not sure if this is the problem. I don't have a production IIS server I cant test it on. I suspect the issue might be with mime type, I am not sure how it works on local system and not your production system but try this code. If it doesn't work I can delete the answer.

Make sure you add the

request.Convert = true;

This tells drive to convert the file to drive format and not just upload an xls for example.

Code

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

        }

Code ripped from Google drive sample project I just added the convert.

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • Still no luck, I see the docx etc as ZIP. – PM. Jul 23 '15 at 09:37
  • check hard coded solution. http://stackoverflow.com/questions/58510/using-net-how-can-you-find-the-mime-type-of-a-file-based-on-the-file-signature dam but that's messy. why is your server returning the wrong mime type.... (Thinking) – Linda Lawton - DaImTo Jul 23 '15 at 09:39
  • 1
    I think we don't have word or excel on our server and hence it is not available in registry. As said here http://stackoverflow.com/questions/3442607/mime-types-in-the-windows-registry – PM. Jul 23 '15 at 09:49
  • 1
    now that makes sense. try changing your code to add the correct mime type of the file not Googles mime type. – Linda Lawton - DaImTo Jul 23 '15 at 09:50
  • yes, hard coded MIME type for these types of files has solved the issue. Thanks a lot. And thank you very much for your great posts... – PM. Jul 23 '15 at 10:14
  • 1
    I am glad we got it working. I think I am going to edit the sample project and do some kind of hard code. This issue may effect others. – Linda Lawton - DaImTo Jul 23 '15 at 10:23