Google Drive API won't download file from IIS
I am using the API client library. API to upload to Google Drive using the Google Drive API using a service account. It works well when I try to run Visual Studio (debug) or even works when I deploy it to local IIS.
But the file doesn't load when deployed to my server (Microsoft Server 2012, IIS 8.5), also doesn't throw any exceptions. Here's a snippet 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 get Null in return. Above the code inside the try and catch block will log an exception, but no exception is thrown.
I have given full access to the IIS user in this folder.
Has anyone faced the same problem? Any pointer to a solution is appreciated.
UPDATE
Works for all files except Office files. Since XLSX etc. Not looking properly on Google Drive, I changed the MIME type as shown below:
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 that I called GetMimeType twice body.MimeType = GetMimeType(uploadFile, false);
and DriveService.Files.Insert(body, stream, GetMimeType(uploadFile))
to get the file uploaded to google drive properly and this is my GetMimeType method:
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;
}
source to share
I'm not sure if this is the problem. I do not have a production IIS server that I cannot test against. I suspect the problem might be with the mime type, I'm not sure how this works on the local system and not your production system, but try this code. If it doesn't work then I can delete the answer.
Make sure you add
request.Convert = true;
This says the disk is converting the file to disk format and not just loading 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 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;
}
}
The code is ripped from the Google Drive Sample Project I just added a converter.
source to share