C# Google Drive APIv3 Upload File

2020-03-21 13:29发布

I'm making a simple Application that Links to a Google Drive Account and then can Upload Files to any Directory and respond with a (direct) download Link. I already got my User Credentials and DriveService objects, but I can't seem to find any good examples or Docs. on the APIv3.

As I'm not very familiar with OAuth, I'm asking for a nice and clear explanation on how to Upload a File with byte[] content now.

My Code for Linking the Application to a Google Drive Account: (Not sure if this works perfectly)

    UserCredential credential;


        string dir = Directory.GetCurrentDirectory();
        string path = Path.Combine(dir, "credentials.json");

        File.WriteAllBytes(path, Properties.Resources.GDJSON);

        using(var stream = new FileStream(path, FileMode.Open, FileAccess.Read)) {
            string credPath = Path.Combine(dir, "privatecredentials.json");

            credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                GoogleClientSecrets.Load(stream).Secrets,
                Scopes,
                "user",
                CancellationToken.None,
                new FileDataStore(credPath, true)).Result;
        }

        // Create Drive API service.
        _service = new DriveService(new BaseClientService.Initializer() {
            HttpClientInitializer = credential,
            ApplicationName = ApplicationName,
        });

        File.Delete(path);

My Code for Uploading so far: (Does not work obviously)

        public void Upload(string name, byte[] content) {

        Google.Apis.Drive.v3.Data.File body = new Google.Apis.Drive.v3.Data.File();
        body.Name = name;
        body.Description = "My description";
        body.MimeType = GetMimeType(name);
        body.Parents = new List() { new ParentReference() { Id = _parent } };


        System.IO.MemoryStream stream = new System.IO.MemoryStream(content);
        try {
            FilesResource.InsertMediaUpload request = _service.Files.Insert(body, stream, GetMimeType(_uploadFile));
            request.Upload();
            return request.ResponseBody;
        } catch(Exception) { }
    }

Thanks!

4条回答
狗以群分
2楼-- · 2020-03-21 13:30

I think you're going in the right direction, just a bit unsure.

The main steps in using the Google Drive API for a C# (.NET) application are

  1. Enable the Google Drive API in your Google Account

  2. Install the Google Drive SDK for .NET framework using "NuGet" package manager. For this, in Visual Studio, go to Tools -> NuGet Package Manager -> Package Manager Console and then enter the following command

    Install-Package Google.Apis.Drive.v3
    
  3. Make sure you "use" all the packages/libraries in your application using the "using" statements at the top. For example,

    using Google.Apis.Auth.OAuth2;
    using Google.Apis.Drive.v3;
    using Google.Apis.Drive.v3.Data;
    using Google.Apis.Services;
    using Google.Apis.Util.Store;
    
  4. The code you have written above seems correct to me (I have not hard tested it). But if you have trouble in uploading files with it, you can try different approaches by the links mentioned below.

The above steps are largely taken from Google Drive API's .NET Quickstart page.

Further, you can and should refer to Google's documentation for the Google Drive SDK for .NET framework.

I hope the above content helped you.

查看更多
一夜七次
3楼-- · 2020-03-21 13:35

Once you have enabled your Drive API, registered your project and obtained your credentials from the Developer Consol, you can use the following code for recieving the user's consent and obtaining an authenticated Drive Service

string[] scopes = new string[] { DriveService.Scope.Drive,
                             DriveService.Scope.DriveFile};
var clientId = "xxxxxx";      // From https://console.developers.google.com
var clientSecret = "xxxxxxx";          // From https://console.developers.google.com
// here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId,
                                                                              ClientSecret = clientSecret},
                                                        scopes,
                                                        Environment.UserName,
                                                        CancellationToken.None,
                                                        new FileDataStore("MyAppsToken")).Result; 
//Once consent is recieved, your token will be stored locally on the AppData directory, so that next time you wont be prompted for consent. 

DriveService service = new DriveService(new BaseClientService.Initializer()
{
   HttpClientInitializer = credential,
   ApplicationName = "MyAppName",
});
service.HttpClient.Timeout = TimeSpan.FromMinutes(100); 
//Long Operations like file uploads might timeout. 100 is just precautionary value, can be set to any reasonable value depending on what you use your service for.

Following is a working piece of code for uploading to Drive.

    // _service: Valid, authenticated Drive service
    // _uploadFile: Full path to the file to upload
    // _parent: ID of the parent directory to which the file should be uploaded

public static Google.Apis.Drive.v2.Data.File uploadFile(DriveService _service, string _uploadFile, string _parent, string _descrp = "Uploaded with .NET!")
{
   if (System.IO.File.Exists(_uploadFile))
   {
       File body = new File();
       body.Title = System.IO.Path.GetFileName(_uploadFile);
       body.Description = _descrp;
       body.MimeType = GetMimeType(_uploadFile);
       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);
       try
       {
           FilesResource.InsertMediaUpload request = _service.Files.Insert(body, stream, GetMimeType(_uploadFile));
           request.Upload();
           return request.ResponseBody;
       }
       catch(Exception e)
       {
           MessageBox.Show(e.Message,"Error Occured");
       }
   }
   else
   {
       MessageBox.Show("The file does not exist.","404");
   }
}

Here's the little function for determining the MimeType:

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

Additionally, you can register for the ProgressChanged event and get the upload status.

 request.ProgressChanged += UploadProgessEvent;
 request.ChunkSize = FilesResource.InsertMediaUpload.MinimumChunkSize; // Minimum ChunkSize allowed by Google is 256*1024 bytes. ie 256KB. 

And

 private void UploadProgessEvent(Google.Apis.Upload.IUploadProgress obj)
 {
     label1.Text = ((obj.ByteSent*100)/TotalSize).ToString() + "%";

    // do updation stuff
 }

That's pretty much it on Uploading..

Source.

查看更多
看我几分像从前
4楼-- · 2020-03-21 13:48

i have the same problem on mine application winforms c# fw 4.0 i installed already google drive api v3 by nuget and also created json file from googles api and inserted into project request.ResponseBody == null???

anyone has a solution for it ?

thanks by advance

查看更多
\"骚年 ilove
5楼-- · 2020-03-21 13:50

If you've followed Google Drive API's .NET Quickstart guide, then you probably remember during first launch, a web page from google drive was prompting for authorization grant to access google drive with "Read only" permission?

The default scope "DriveService.Scope.DriveReadonly" from the quickstart guide can't be used if you intend on uploading files.

This worked for me

  1. Remove "Drive ProtoType" from Apps connected to your account

  2. Create another set of credentials with a new application name eg "Drive API .NET Quickstart2" in API Manager

  3. Request access with this scope "DriveService.Scope.DriveFile" private static readonly string[] Scopes = { DriveService.Scope.DriveReadonly }; private static readonly string ApplicationName = "Drive API .NET Quickstart2";}

  4. You should land on a new page from google drive requesting new grant

    Drive Prototype would like to: View and manage Google Drive files and folders that you have opened or created with this app

After allowing access, your application should be able to upload.

查看更多
登录 后发表回答