Google Drive API with C# .net – Upload 68


Please Share

Google Drive APIHave you been trying to connect your website or application to Google Drive?  Would you like to see a list of files or a list of Directories stored on Google Drive?   Would you like to Upload a file to Google Drive or download a file from Google drive using C# .Net using Visual Studio.   In this tutorial series, we will be looking into the Google Drive API, using the Google .net Client library which makes accessing Google APIs much simpler.    There are a lot of things you can do with the Google Drive API, List files and folders,  Download files, Upload files, Change Files,  Copy files,  Delete Files, Trash Files,  Create directory’s, delete directory’s.  There is even a version of %appdata% on Google Drive where you can store your application specific files for each user.



Five part Tutorial Series

  1. Google Drive API with C# .net – Authentication
  2. Google Drive API with C# .net – Files –  Files, directories, search
  3. Google Drive API with C# .net – Upload, update, patch, delete, trash
  4. Google Drive API with C# .net – Download
  5. Google Drive API with C# .net – File Permissions
  6. Google Drive API with C# .net – Sample project

 

Restringing your application.

Like with most of the Google APIs you need to be authenticated in order to connect to them. To do that you must first register your application on Google Developer console.   Under APIs be sure to enable the Google Drive API and Google Drive SDK, as always don’t forget to add a product name and email address on the  consent screen form.

Project Setup

Make sure your project is at least set to .net 4.0.

Add the following NuGet Package

PM> Install-Package Google.Apis.Drive.v2

You will probably need most of these using’s

using System;
using Google.Apis.Drive.v2;
using Google.Apis.Auth.OAuth2;
using System.Threading;
using Google.Apis.Util.Store;
using Google.Apis.Services;
using Google.Apis.Drive.v2.Data;
using System.Collections.Generic;

Authentication

This tutorial assumes that you have already read the tutorial about Google Drive API with C# .net – Authentication. I will not be going into how to create a valid Drive service if you haven’t created one already please go read that tutorial then come back here.
Now we have a drive service that we can preform perform though.

Upload

Directory

Remember directory’s are nothing but files with a different mime type.  The following method will create a new allow you to create a new directory. Send parent = root if you would like it at the top directory. Other wise it must be a valid directory file resource id, you can get this using list with search to find the directory you are looking for.

   //// 
   /// Create a new Directory.
   /// Documentation: https://developers.google.com/drive/v2/reference/files/insert
   /// 
   /// a Valid authenticated DriveService
   /// The title of the file. Used to identify file or folder name.
   /// A short description of the file.
   /// Collection of parent folders which contain this file. 
   ///                       Setting this field will put the file in all of the provided folders. root folder.
   /// 
        public static File createDirectory(DriveService _service, string _title, string _description, string _parent) {

            File NewDirectory = null;

            // Create metaData for a new Directory
            File body = new File();
            body.Title = _title;
            body.Description = _description;
            body.MimeType = "application/vnd.google-apps.folder";            
            body.Parents = new List() { new ParentReference() { Id = _parent } };
            try
            {
                FilesResource.InsertRequest request = _service.Files.Insert(body);
                NewDirectory = request.Execute();
            }
            catch (Exception e)
            {
                Console.WriteLine("An error occurred: " + e.Message);
            }

            return NewDirectory;
        }

Files

Remember from creating a directory in order to upload a file you have to be able to tell Google what its mime-type is.  I have a little method here that try’s to figure that out.   Just send it the file name.   Note: When uploading a file to Google Drive if the name of the file is the same name as a file that is already there.   Google Drive just uploads it anyway,  the file that was there is not updated you just end up with two files with the same name.     It only checks based on the fileId not based upon the file name.    If you want to Update a file you need to use the Update command we will check that later.

// tries to figure out the mime type of the file.
 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;
        }

With that we can continue.

  /// 
  /// Uploads a file
  /// Documentation: https://developers.google.com/drive/v2/reference/files/insert
  /// 
  /// a Valid authenticated DriveService
  /// path to the file to upload
  /// Collection of parent folders which contain this file. 
  ///                       Setting this field will put the file in all of the provided folders. root folder.
  /// If upload succeeded returns the File resource of the uploaded file 
  ///          If the upload fails returns null
        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() { 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.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;
            }           
        
        }

Just like with creating a directory we need to supply our meta data information.    We are using the GetMimeType method to find out the files mimetype.   Then we are loading the File into a MemoryStream that we can use to send to service.Files.Insert.      Once the file is done uploading you can get the request.ResponseBody and check for any errors.   If a file.id is returned you know your file has now been uploaded.

Update

Google Drive is a little strange in my opinion. If you take the same fine and upload it again, you end up with two files. Personally i would rather see the first one over written, but thats not how Google has chosen to do things. So that is where update comes in. If you want to make a change to a file then you will need to update the file. To update a file in Google drive you will need the file resource id of the file you would like to update.

 
        /// 
        /// Updates a file
        /// Documentation: https://developers.google.com/drive/v2/reference/files/update
        /// 
        /// a Valid authenticated DriveService
        /// path to the file to upload
        /// Collection of parent folders which contain this file. 
        ///                       Setting this field will put the file in all of the provided folders. root folder.
        /// the resource id for the file we would like to update                      
        /// If upload succeeded returns the File resource of the uploaded file 
        ///          If the upload fails returns null
        public static File updateFile(DriveService _service, string _uploadFile, string _parent,string _fileId)
        {

            if (System.IO.File.Exists(_uploadFile))
            {
                File body = new File();
                body.Title = System.IO.Path.GetFileName(_uploadFile);
                body.Description = "File updated by Diamto Drive Sample";
                body.MimeType = GetMimeType(_uploadFile);
                body.Parents = new List() { 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.UpdateMediaUpload request = _service.Files.Update(body, _fileId, stream, GetMimeType(_uploadFile));
                    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;
            }

        }

Notice how this time we use service.files.update() and we get an FileRecources.UpdateMediaUpload back. You probably don’t want to to loop though all of the files updating them all. It would probably make more sense to figure out exactly which file it is.

Patch

There is a second way to Update a file.  If all you want to do is change its meta data then you can use Patch.

File file = new File();
file.Title = newTitle;
// Rename the file.
FilesResource.PatchRequest request = service.Files.Patch(file, fileId);
File updatedFile = request.Fetch();

This will simply rename the file with out changing the continence of file itself.

Delete

Finally we come to delete.   Delete like Update and upload requires the fileId.   Use the same code as we used above only instead of all the Metadata and stream stuff just use this

FilesResource.DeleteRequest DeleteRequest = service.Files.Delete(file.Id);
DeleteRequest.Execute();

This will permanently delete the file with that id.  It skips the trash.

Trash

Instead of permanently deleting a file you can simply trash it.

service.files().trash(fileId).execute();

You can also untrash a file

service.Files.Untrash(fileId).Fetch();

Trashing is probably better then deleting unless you ask the user if they are sure they want to delete the file.

Concision

You should now understand how to access the Google Drive API with an authenticated user. You should also understand how to upload files to Google Drive, how to update a file on Google Drive. We have also talked about the difference between deleting and trashing files from Google Drive. I hope you will also agree that working with the Google APIs is quite easy once you get the authentication down.

Blog authors who like to make people happy and help them enjoy working with the Google APIs, release the code to go along with this tutorial on GitHub: Google Drive API with C# .net – Sample project

Please Share


Linda Lawton

About Linda Lawton

My name is Linda Lawton I have more than 20 years experience working as a developer and a database expert. I have been working with several of the Google APIs, since 2012. I helping others in the On-Line community to develop with the Google APIs, by creating my own blog www.daimto.com. This and my presence on a number of On-Line developer forums lead me to be noticed by the Google Analytics API development team. I was nominated for and recently became one of the first Google Developer Experts for Google Analytics.


Leave a comment

Your email address will not be published. Required fields are marked *

68 thoughts on “Google Drive API with C# .net – Upload

  • Matt Orton

    This is good stuff. It is nice to find all this information in one place. And it is very concisely written.
    You should have someone proof read it though. The typo-s detract from your expert instruction.

  • Alberto

    Your site is really helpful thanks for your work ! I have 2/3 questions:
    -do you have any sample to show how to change permission on an uploaded file ?
    – when you upload a file with a service account how can you find your file with the standard drive web interface ?
    I cannot understand with the service account which user space they are consuming
    Thanks
    Alberto

    • Administrator
      Linda Lawton

      A service account is its own sudo user, it has a google drive account, a google calendar account … probably a bunch more. Any files uploaded to the service account cant be seen though the web intervace unless you give say yourself or someone else access to the file. I havent added that to the sample project but i can put it on my list.

      I found this in the documentation though: Permissions:patch

      ///

      /// Patch a permission's role.
      ///

      /// Drive API service instance.
      /// ID of the file to update permission for.
      /// ID of the permission to patch.
      /// The value "owner", "writer" or "reader".
      /// The patched permission, null is returned if an API error occurred
      public static Permission PatchPermission(DriveService service, String fileId,
      String permissionId, String newRole) {
      Permission patchedPermission = new Permission();
      patchedPermission.Role = newRole;
      try {
      return service.Permissions.Patch(patchedPermission, fileId, permissionId).Execute();
      } catch (Exception e) {
      Console.WriteLine("An error occurred: " + e.Message);
      }
      return null;
      }

  • Alberto

    Does this mean I can login in google with the service account on the web and see calendar / drive and other stuff ? thanks for your help

  • Jamie

    Your code is very helpful. I have tried to work out how to edit an existing spreadsheet. All I can find is for gdata and I believe that it no longer works. I want to add data from another source to the sheet. Any pointer or help would be appreciated.

  • Nutan Patel

    Your article is very nice. It helps me to do almost all operation but I am not able to delete file from the drive.
    Issue:
    Few files were previously uploaded so their owner is xyz@domain.com. Now we have created service account using this domain account but we are not able to delete those files as owner is different.

    Any solution ??

    Thanks in advance.

    • Administrator
      Linda Lawton

      The owner of the file will either have to delete them himself / herself or grant the service account access to delete the files. No one can delete files owned by someone else not even a mighty service account 🙂 Congrats on getting this far.

          • Nutan Patel

            What do you mean by full access ? I can give “Can Edit” access to service account but it does not allow me to delete the file. And I am not able to make service account “Is Owner” because it gives me error like “Ownership can not be transferred in different domain.”

            I got the error but I want to know is there any way to transfer ownership from xyz@domain.com to service account email id (random generated by key) ?

          • Administrator
            Linda Lawton

            I am actually not sure this is even possible. I have seen a number of people trying but i don’t have access to a domain account to test with. try asking on stackoverflow.com maybe someone there knows.

  • Saeed Nemati

    I did enjoy reading your tutorials. I was about to create an application that needed a huge amount of storage, so I chose Google Drive, and I was somehow stuck in how to programmatically manage it. Your articles was of great help. Thank you.

  • Ishay

    Hi, I use the upload method, but receive request.ResponseBody = null and the following exception ‘Value cannot be null.Parameter name: baseUri’, what can be the problem?

        • Administrator
          Linda Lawton

          request.ResponseBody; only returns if your file was uploaded successfully. You need to figure out why your file wasn’t uploaded. start with a easy empty text file or something debug your way up.

          • Ishay

            The base uri That I see in the service is “https://www.googleapis.com/drive/v2/” and this is the answer I receive from Google after I send RefreshToken, ClientId and ClientSecret.
            I tried to browse and got Not Found – what do I need to get a valid url?

  • Ishay

    Ok…. I found the problem – After updating via nuget Zlib.Portable is updated to version 1.110.0, while Google is using version 1.10.00 — that was frustrating and I’m glad I manage to find what was the problem – Thanks for your patient and for answers

        • Ray

          Your articles have been a great help in enabling me to understand working with the Google Drive API. Using them I have managed to write a small program that can authenticate, down load a list of files and also using one of the file IDs download the file to my hard drive. However I cannot get a file to upload. Using the code above I get the same error as Ishay – Value cannot be null. I am also using the ZLib.portable version 1.110.0. Sorry but I do not understand how to get past this problem. Can you please offer some help?

  • prasad

    can you provide sample code cos i am new to mvc and is there any solution to upload files in sites admin’s single account using mvc or some links that will help me to achieve this???

  • harikrishna parmar

    hi.. i create project using google drive.
    i can’t upload any file on google drive as this stuff.

    ClientSecrets secrets = new ClientSecrets()
    {
    ClientId = parameters.ClientId,
    ClientSecret = parameters.ClientSecret
    };
    var token = new TokenResponse { RefreshToken = parameters.RefreshToken };
    var credentials = new UserCredential(new GoogleAuthorizationCodeFlow(
    new GoogleAuthorizationCodeFlow.Initializer
    {
    ClientSecrets = secrets
    }),
    “xxxx@gmail.com”,
    token);

    var service = new DriveService(new BaseClientService.Initializer()
    {
    HttpClientInitializer = credentials,
    ApplicationName = “Google Drive”,
    });
    if (FileUpload1.HasFile)
    {
    var filename = FileUpload1.FileName;
    var filepath = FileUpload1.PostedFile.FileName;

    Google.Apis.Drive.v2.Data.File body = new Google.Apis.Drive.v2.Data.File();
    body.Title = filename;
    body.Description = “Documents”;
    body.MimeType =GetMimeType(filename);
    body.Parents = new List() { new ParentReference() { Id =”root” } };
    //byte[] array = System.IO.File.ReadAllBytes(filepath);
    System.IO.MemoryStream stream = new System.IO.MemoryStream(FileUpload1.FileBytes);

    FilesResource.InsertMediaUpload fileuploadrequest = new FilesResource.InsertMediaUpload(service, body, stream, GetMimeType(filename));

    var name=MediaFileSource.GetContentTypeForFileName(filename);
    fileuploadrequest.Convert = true;
    fileuploadrequest.Upload();

    Google.Apis.Drive.v2.Data.File response = fileuploadrequest.ResponseBody;

    response is null…

    please give me asolution for this
    thanks…

  • Akshita Gupta

    Hi Linda

    Thanks for great tutorials. These have helped me to get started and have a better understanding of the api.

    I have a doubt and I hope you could help in figuring out. Here is my problem description:

    I am using google drive v3 api to upload a file and then preview it in browser using web view link in the response. But web view link is coming null. When i was using v2, I was able to do it using alternate link.

    I have not set the parent ref so I am assuming as per the documentation, the file is stored in my drive folder(root) of service account. As I couldn’t login to service account, so I shared the file with my existing test gmail account and it was shared.

    My question is how can I open the file in browser using System.Diagnostics.Process.Start(newFile.WebViewLink);

    here is my code:

    {
    File fileInGoogleDrive = Utils.uploadToDrive(service, pathOfTheFileToBeUploaded, “root”); // code of this method below

    Permission toShare = new Permission();
    toShare.EmailAddress = “xyz@gmail.com”;
    toShare.Type = “user”;
    toShare.Role = “reader”;

    PermissionsResource.CreateRequest createRequest = service.Permissions.Create(toShare, fileInGoogleDrive.Id);
    createRequest.Execute();

    return fileInGoogleDrive.WebViewLink; //THIS IS NULL
    }

    // Upload to drive code

    public static File uploadToDrive(DriveService _service, string _uploadFile, string _parent = “root”)
    {

    if (!String.IsNullOrEmpty(_uploadFile))
    {

    File fileMetadata = new File();
    fileMetadata.Name = System.IO.Path.GetFileName(_uploadFile);
    fileMetadata.MimeType = GetMimeType(_uploadFile);
    //fileMetadata.Parents = new List() { new FilesResource() {}};

    try
    {
    byte[] byteArray = System.IO.File.ReadAllBytes(_uploadFile);
    System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
    FilesResource.CreateMediaUpload request = _service.Files.Create(fileMetadata, stream, GetMimeType(_uploadFile));
    request.Upload();
    return request.ResponseBody;

    }
    catch (System.IO.IOException iox)
    {
    // Log
    return null;
    }
    catch (Exception e) // any special google drive exceptions??
    {
    //Log
    return null;
    }
    }
    else
    {
    //Log file does not exist
    return null;
    }
    }

    I will be really grateful if you guide me on this.

    Thanks in advance 🙂

  • Akshita Gupta

    Hi Lynda

    WRT my previous comment, I figured out the syntax of getting fields from v3 api to get webViewLink. Wanted to know the second part of how I can view it in browser. As this is the service account, the link generated tells needs permission. So when I add permission for another user, I can see the file inside the drive after logging in. How can I get that share url or how can the service account delegate control such that the file opens up in browser after getting data from drive api?

    Web Search shows me using domain wide delegation and adding permissions for another user. i tried the permissions one and as told above, I wanted to pop the file in browser after getting results and not check in that user’s drive.

    Sorry about the long post but I am confused with the logic here.

  • Mr Cheong

    Hi DalmTo,
    I had read through your article, I want to upload a file, when i copy your code in my console application. body.Parents = new List() { new ParentReference() { Id = _parent } }; the List() will get has the error, may i know how to solve it.

      • JCano

        This one:
        CS1922 Cannot initialize type ‘List’ with a collection initializer because it does not implement ‘System.Collections.IEnumerable’

      • JCano

        This one:
        CS1922 Cannot initialize type ‘List’ with a collection initializer because it does not implement ‘System.Collections.IEnumerable’

        In order to work, changed it to:
        body.Parents = new List() { new ParentReference() { Id = _parent } };

      • JCano

        This one:
        CS1922 Cannot initialize type ‘List’ with a collection initializer because it does not implement ‘System.Collections.IEnumerable’

        In order to work, changed it to:
        body.Parents = new List() { new ParentReference() { Id = _parent } };

        (You may delete the previous posts, made a mess)

  • Karsten

    Hi Linda, great samples !
    I have created a method based on your sample ‘updateFile’ . I use google drive v3. my methods runs without any error, but the content of the targetfile does not change. uploading an deleting files on my drive-account works fine.
    Do you have any idea why the method failed?

    In v3 there are two functions for updating files. first creates a UpdateRequest to patch metadata and second creates a UpdateMediaUpload to update content. my method uses the second one.

    • Linda Lawton
      Linda Lawton Post author

      unfortunately all i have done is generate some sample code for v3 i haven’t tried to use it yet. I will find sometime this week to take a look. Google hasn’t uploaded any tutorials for it yet i think its time i do.

      • Karsten

        i resolved it by myself (and with forum: After update to API v3 Update won’t work Link => https://github.com/google/google-api-dotnet-client/issues/668).

        The error results because of using non writeable fields for File-Parameter. I took the File-Instance from a previous Get() -Call.

        If i create an empty File-Parameter and set only the Name-attribute, the function works. The last question is: Which attributes are writeable? But this has to be specified by google.
        thanks

  • Jan

    Hello there Maam Linda. I reading your article and very interested on your tutorial. Right know, i followed your tutorial but unlucky I was unable to upload file. Could you give a sample project that I could just change the client id and client key? So that I could try uploading files in my google drive. I am really new in c#, I am just using it 2 weeks right now. Hope you helps me. Thanks and advance

      • Jan

        Hello there!
        Thank you for the help
        I already understand how it works.
        Could I ask I am trying to save all images in a folder. when i try root/Image which is the image is my folder it doesn’t upload file. Could you help me with this problem

        • Linda Lawton
          Linda Lawton Post author

          Files.insert

          parents[] list Collection of parent folders which contain this file.
          Setting this field will put the file in all of the provided folders. On insert, if no folders are provided, the file will be placed in the default root folder.

          // Set the parent folder.
          if (!String.IsNullOrEmpty(parentId)) {
          body.Parents = new List()
          {new ParentReference() {Id = parentId}};
          }

          You need to get the id of the image folder. Try using files.list to find it.

          • Jan

            Getting the ID of the folder do the trick.
            I can now upload image in my folder.
            Thank you for the great tutorial.

  • Jan

    Hello there!
    Thank you for the help
    I already understand how it works.
    Could I ask I am trying to save all images in a folder. when i try root/Image which is the image is my folder it doesn’t upload file. Could you help me with this problem

  • Hassaan Kamran

    Dear Linda,
    Its really a helpful article but i have one query.

    I have created a folder in google drive directly from web. Now i want to create file in that folder. You have said that i need directory file resource id of that folder in order to create file in that folder. I know a name of that folder but i dont know how to get its Id. Can you please guide me. Code snippet will be helpful.

    Regards,
    Hassaan Kamran

  • Divins Mathew

    Thanks. It works great. But when i try to upload bigger files (like 100 MB) , Visual Studio throws TaskCancelledException with additional information : “A task was cancelled.” and the upload is aborted half way. Why does this happen? And how do I fix it? Thanks.

  • John

    Is there a page like this for v3? This page has several syntax errors in Upload File when using v3.
    – GetMimeType
    – InsertMediaUpload
    – ParentReference
    – Files.Insert

    • Linda Lawton
      Linda Lawton Post author

      Net yet I am working on getting a v3 sample project together. Then putting some tutorials up for it. Google hasn’t made any documentation for it for C# yet I guess I need to do that for us.

  • kandeepan

    I need to check free space i got the code but not, working

    About about = service.About.Get().Execute();

    about.QuotaBytesTotal=”Total bytes is coming”
    about.QuotaBytesUsed=”0″ is coming

    How to slove this