In some web-application we may need to upload files on Google Drive, so in this post I have explained how we can use Google Drive API and OAuth2 to upload any type of file on Google drive using ASP.NET MVC C#.
Create a new project in Visual Studio for ASP.NET MVC
Let's begin by creating new project in Visual Studio, navigate to File-> New -> Project -> Select "ASP.NET web-application" from right pane and Select "Web" from left pane -> Enter project name ( GoogleDriveUploadMVC ) and Click "OK"
In Next Screen select "MVC" as template and then Click "OK"
Create new project in Google Developer Console
Before we move any further with our MVC project, we need to create a new project in Google developer console to get OAuth2 details.
Go to https://console.developers.google.com/cloud-resource-manager
Click on "Create project"
In the Next Screen, Enter project name and select Organization (if any applicable, default is No Orgnization) and Click "Create"
Once you have created the project, you can open the Google Cloud platform dashboard ( https://console.cloud.google.com/home/dashboard ), it will open the recently created project by default, if not you can select the project from top left.
Once you have opened the dashboard, navigate to "API & services"-> "Dashboard"
Now, we need to enable "Google Drive API", so click on "Enable APIS and Services" and then search for "Google Drive API" on next screen search box, once you have selected "Google Drive API", enable it
Create OAuth Consent and Credentials
Once we have Enabled the Google Drive API, we need to create credentials, and save details OAuth Consent Screen.
Let's save details in OAuth Consent Screen, and enter the "Application Name" and save details
Now, we need to navigate to "Credentials" and create a new credentials for MVC application by Clicking on "Create Credentials" -> Select "OAuth Credentials" -> Select "Web application" -> Enter Name of application -> Enter "Auhtorised redirect URI" url properly otherwise you might get error ("400. That’s an error. Error: redirect_uri_mismatch - Google OAuth Authentication")
After creating it, you will the next screen, with client-secret and client-id, close it and download credentials in JSON format and save it in root directory of your project.
Install Nuget package for Google Drive API in MVC application
Once we have Client Id/Secret from google developer console, we can go back to our MVC web-application and install Nuget package for Google Drive API.
So, navigate to "Tools"-> "Nuget Package Manager" -> "Manage Nuget Packages for solution" -> Select "Browse" -> Search for "Google Drive API"
Create Google Drive API service class in MVC project
Once you have installed the Google API from Nuget, go to your project, right-click on Models folder and add a new class "GoogleDriveAPIHelper.cs", in this class we will initialize Google Drive API using Credentials created in above steps.
So, here is the code for "GoogleDriveAPIHelper.cs" to initialize service and upload files on it.
public class GoogleDriveAPIHelper
{
//add scope
public static string[] Scopes = { Google.Apis.Drive.v3.DriveService.Scope.Drive };
//create Drive API service.
public static DriveService GetService()
{
//get Credentials from client_secret.json file
UserCredential credential;
//Root Folder of project
var CSPath = System.Web.Hosting.HostingEnvironment.MapPath("~/");
using (var stream = new FileStream(Path.Combine(CSPath, "client_secret_860319795502-th86n6pjkjmc53j0503u22j16a9r3c2r.apps.googleusercontent.com.json"), FileMode.Open, FileAccess.Read))
{
String FolderPath = System.Web.Hosting.HostingEnvironment.MapPath("~/"); ;
String FilePath = Path.Combine(FolderPath, "DriveServiceCredentials.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(FilePath, true)).Result;
}
//create Drive API service.
DriveService service = new Google.Apis.Drive.v3.DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "GoogleDriveMVCUpload",
});
return service;
}
//file Upload to the Google Drive root folder.
public static void UplaodFileOnDrive(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
//create service
DriveService service = GetService();
string path = Path.Combine(HttpContext.Current.Server.MapPath("~/GoogleDriveFiles"),
Path.GetFileName(file.FileName));
file.SaveAs(path);
var FileMetaData = new Google.Apis.Drive.v3.Data.File();
FileMetaData.Name = Path.GetFileName(file.FileName);
FileMetaData.MimeType = MimeMapping.GetMimeMapping(path);
FilesResource.CreateMediaUpload request;
using (var stream = new System.IO.FileStream(path, System.IO.FileMode.Open))
{
request = service.Files.Create(FileMetaData, stream, FileMetaData.MimeType);
request.Fields = "id";
request.Upload();
}
}
}
}
In the above Class we have two methods, one to upload file on drive and another to initialize Google Drive Service using the Credentials in JSON downloaded from Google developer console for OAuth 2
You will also need to create folder named "GoogleDriveFiles" in the root of your project, to upload user files there in your project.
Now go to your Index.cshtml view inside "Home" Folder, and use the below Razor code to upload file
@{
ViewBag.Title = "Home Page";
}
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="row" style="margin-top:10px;margin-bottom:10px;">
<div class="col-md-2"><label for="file">Upload file on drive:</label></div>
<div class="col-md-10">
<input type="file" name="file" id="file" />
</div>
<div class="col-md-2">
<br/>
<input type="submit" class="btn btn-success" value="Upload" />
</div>
</div>
}
@ViewBag.Success
In your HomeController.cs, call the above created GoogleDriveHelper.cs class and upload file on google drive
using GoogleDriveUploadMVC.Models;
using System.Web;
using System.Web.Mvc;
namespace GoogleDriveUploadMVC.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
GoogleDriveAPIHelper.UplaodFileOnDrive(file);
ViewBag.Success = "File Uploaded on Google Drive";
return View();
}
}
}
That's it, we are done, now we can build and run the project in browser.
You will output as below
Note: Browser may ask you to login into your account. Also, you may get not authorised redirect URL error, if yes go to your OAuth Credentials page and enter correct Authorised URL.(400. That’s an error. Error: redirect_uri_mismatch - Google OAuth Authentication)
You will see uploaded file on your google drive.
That's it, we are done with uploading file on google drive. You can upload anytype of file on google drive by providing it's mimetype while uploading the file.
Note: Above C# Code will work for local user, if you are trying to upload files on Google Drive using your own credentials. As
GoogleWebAuthorizationBroker.AuthorizeAsync
this method is designed for use with an installed application.
Few more google drive api helpful functions in C#
We are done with uploading part, here are few more helpful functions using Google Drive API and C#
List all files of Google Drive
//get all files from Google Drive.
public static List<GoogleDriveFile> GetDriveFiles()
{
Google.Apis.Drive.v3.DriveService service = GetService();
// Define parameters of request.
Google.Apis.Drive.v3.FilesResource.ListRequest FileListRequest = service.Files.List();
// for getting folders only.
//FileListRequest.Q = "mimeType='application/vnd.google-apps.folder'";
FileListRequest.Fields = "nextPageToken, files(*)";
// List files.
IList<Google.Apis.Drive.v3.Data.File> files = FileListRequest.Execute().Files;
List<GoogleDriveFile> FileList = new List<GoogleDriveFile>();
// For getting only folders
// files = files.Where(x => x.MimeType == "application/vnd.google-apps.folder").ToList();
if (files != null && files.Count > 0)
{
foreach (var file in files)
{
GoogleDriveFile File = new GoogleDriveFile
{
Id = file.Id,
Name = file.Name,
Size = file.Size,
Version = file.Version,
CreatedTime = file.CreatedTime,
Parents = file.Parents,
MimeType = file.MimeType
};
FileList.Add(File);
}
}
return FileList;
}
For using above function you would have to create another class "GoogleDriveFile.cs"
using System;
using System.Collections.Generic;
namespace GoogleDriveUploadMVC.Models
{
public class GoogleDriveFile
{
public string Id { get; set; }
public long? Size { get; set; }
public string Name { get; set; }
public long? Version { get; set; }
public DateTime? CreatedTime { get; set; }
public IList<string> Parents { get; set; }
public string MimeType { get; set; }
}
}
C# function for Downloading File From Google
//Download file from Google Drive by fileId.
public static string DownloadGoogleFile(string fileId)
{
DriveService service = GetService();
string FolderPath = HttpContext.Current.Server.MapPath("/GoogleDriveFiles/");
FilesResource.GetRequest request = service.Files.Get(fileId);
string FileName = request.Execute().Name;
string FilePath = Path.Combine(FolderPath, FileName);
MemoryStream stream1 = new MemoryStream();
// Add a handler which will be notified on progress changes.
// It will notify on each chunk download and when the
// download is completed or failed.
request.MediaDownloader.ProgressChanged += (IDownloadProgress progress) =>
{
switch (progress.Status)
{
case DownloadStatus.Downloading:
{
Console.WriteLine(progress.BytesDownloaded);
break;
}
case DownloadStatus.Completed:
{
Console.WriteLine("Download complete.");
SaveStream(stream1, FilePath);
break;
}
case DownloadStatus.Failed:
{
Console.WriteLine("Download failed.");
break;
}
}
};
request.Download(stream1);
return FilePath;
}
// file save to server path
private static void SaveStream(MemoryStream stream, string FilePath)
{
using (FileStream file = new FileStream(FilePath, FileMode.Create, FileAccess.ReadWrite))
{
stream.WriteTo(file);
}
}
Creating Folder on Google Drive using C#
// Create Folder in root
public static void CreateFolder(string FolderName)
{
DriveService service = GetService();
var FileMetaData = new Google.Apis.Drive.v3.Data.File();
FileMetaData.Name = FolderName;
//this mimetype specify that we need folder in google drive
FileMetaData.MimeType = "application/vnd.google-apps.folder";
FilesResource.CreateRequest request;
request = service.Files.Create(FileMetaData);
request.Fields = "id";
var file = request.Execute();
}
Basically in the above code we are specifying FileMetaData.MimeType = "application/vnd.google-apps.folder" to create folder on Google Drive
Upload files inside folder
// File upload in existing folder
public static void FileUploadInFolder(string folderId, HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
//create service
DriveService service = GetService();
//get file path
string path = Path.Combine(HttpContext.Current.Server.MapPath("~/GoogleDriveFiles"),
Path.GetFileName(file.FileName));
file.SaveAs(path);
//create file metadata
var FileMetaData = new Google.Apis.Drive.v3.Data.File()
{
Name = Path.GetFileName(file.FileName),
MimeType = MimeMapping.GetMimeMapping(path),
//id of parent folder
Parents = new List<string>
{
folderId
}
};
FilesResource.CreateMediaUpload request;
//create stream and upload
using (var stream = new System.IO.FileStream(path, System.IO.FileMode.Open))
{
request = service.Files.Create(FileMetaData, stream, FileMetaData.MimeType);
request.Fields = "id";
request.Upload();
}
var file1 = request.ResponseBody;
}
}
In the above code, the only difference from file upload version is that we are providing parent folder id, you can get all folders and it's id using below function
public static List<GoogleDriveFile> GetDriveFolders()
{
DriveService service = GetService();
List<GoogleDriveFile> FolderList = new List<GoogleDriveFile>();
FilesResource.ListRequest request = service.Files.List();
request.Q = "mimeType='application/vnd.google-apps.folder'";
request.Fields = "files(id, name)";
Google.Apis.Drive.v3.Data.FileList result = request.Execute();
foreach (var file in result.Files)
{
GoogleDriveFile File = new GoogleDriveFile
{
Id = file.Id,
Name = file.Name,
Size = file.Size,
Version = file.Version,
CreatedTime = file.CreatedTime
};
FolderList.Add(File);
}
return FolderList;
}
These are most used functions of Google Drive API in C#.
You can download sample project. Before using sample project, create your Google console project and download credentials as explained above.
You may also like to read:
Using Google Charts in ASP.NET MVC (With Example)
Showing Google Maps in ASP.NET MVC with Marker (Lat/Long data from database)
vikas_jk
Hello, Thanks for giving details, looks like you haven't got credentials from google correctly.
Make sure you have enabled all API's on Google Dashboard and also downloaded JSON credentials on correct path, and if it is accessible.
Debug your code line by line in VS here.
Thanks.
jamiedewitz
Thank you for that. I get to this piece:
and then get a redirect error, that shows this uri, which is not what I put in Google developer.
This works with a web application, right? I'm not using a standalone app, this is running from a website.