Skip to main content

Google Drive API: Folder & Inserting a file

Cloud Storage Access through API - ASP.NET MVC 5 - C# (Part-3) 

Google Drive API v2 & v3 - a) Creating a folder, 
                                               b) Inserting a file in a folder. 
                                               C) Get Folder Content.      
       
Suggested Video:  1) Google Drive API - Enable for Application. 
                                2) Google Drive API - File Upload, View, Download & Delete 
                                   3) Google Drive API - Create folder, Upload file to folder, Show folder Contain. 
                                   4) Google Drive API - Move & Copy files between folders.
                                   5) Google Drive API - Manage Share & Set User Role Permissions.
                                   6) Google Drive API - View Share Users Permission Details.

Source Code:  Click to download [11.1 MB]

In Part-2 of this video series, we have seen "File Uploading, Viewing, Downloading & Deleting in Google Drive using Google Drive API v3 ". 



Before I continue this, we need to know some key concepts of google drive. Key Concepts are:

Upload a file or create a folder in google drive :
1) Google drive create a unique ID for each & every item in the drive. 
2) We create & upload same name folder and files in multiple time in the same location in google drive. Google drive is identified this item by the unique IDs. 

So, Next question in our mind how to identifies a file or folder in google drives.

A) How to Identifies a file or folder in Google Drive? 
  1) A File has size property but folder has no size property. 
  2) Difference between a File MIME Type and Folder MIME Type.
  3) A folder content - a) may be empty 
                                    b) one/more files or folders.  
     A File has raw information. 

In this tutorials, I use file size property of Google drive API.

B) Create a folder in Google Drive using API?


When we creating a folder into the google drive, just like a file, google drive provide a specific unique folder id for the newly created folder. But In this case, we need to provide MIME type for folder "application/vnd.google-apps.folder"

Please see this code: 

public static void CreateFolder(string FolderName)
        {
            Google.Apis.Drive.v3.DriveService service = GetService_v3();

            Google.Apis.Drive.v3.Data.File FileMetaData = new Google.Apis.Drive.v3.Data.File();
            FileMetaData.Name = FolderName;
            FileMetaData.MimeType = "application/vnd.google-apps.folder";

            Google.Apis.Drive.v3.FilesResource.CreateRequest request;

            request = service.Files.Create(FileMetaData);
            request.Fields = "id";
            var file = request.Execute();
        }

C) Inserting a file in a folder using Google Drive API?


Inserting a file in particular folder, specify the correct folder id in the parent property of the google drive file. 

Please see this code: 

public static void FileUploadInFolder(string folderId, HttpPostedFileBase file)
        {
            if (file != null && file.ContentLength > 0)
            {
                Google.Apis.Drive.v3.DriveService service = GetService_v3();

                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()
                {
                    Name = Path.GetFileName(file.FileName),
                    MimeType = MimeMapping.GetMimeMapping(path),
                    Parents = new List<string>
                    {
                        folderId
                    }
                };
                Google.Apis.Drive.v3.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();
                }
                var file1 = request.ResponseBody;
            }
        }

C) Get Folder Content using Google Drive API?



We need to specify the correct folder id of folders. 

Please see this code: 

public static List<GoogleDriveFiles> GetContainsInFolder(String folderId)
        {
            List<string> ChildList = new List<string>();
            Google.Apis.Drive.v2.DriveService ServiceV2 = GetService_v2();
            ChildrenResource.ListRequest ChildrenIDsRequest = ServiceV2.Children.List(folderId);
            do
            {
                ChildList children = ChildrenIDsRequest.Execute();

                if (children.Items != null && children.Items.Count > 0)
                {
                    foreach (var file in children.Items)
                    {
                        ChildList.Add(file.Id);
                    }
                }
                ChildrenIDsRequest.PageToken = children.NextPageToken;

            } while (!String.IsNullOrEmpty(ChildrenIDsRequest.PageToken));

            //Get All File List
            List<GoogleDriveFiles> AllFileList = GetDriveFiles();
            List<GoogleDriveFiles> Filter_FileList = new List<GoogleDriveFiles>();

            foreach (string Id in ChildList)
            {
                Filter_FileList.Add(AllFileList.Where(x => x.Id == Id).FirstOrDefault());
            }
            return Filter_FileList;
        }

Let's do it using Visual Studio MVC Application

First, Goto the Visual Studio 2013 or Higher Version.

Step 1: Create an Empty MVC Project. Name of the project: GoogleDriveRestAPI.
Step 2: Opening the NuGet Package Manager Console, Select the package source and run this following two command. 

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

Here I am using Google Drive API v2 & v3, 

Step 3 (Model): 
First, we need to create a model class (Name: GoogleDriveFiles.cs) under the Model folder of project solution. Please Copy & Paste this code into this class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace GoogleDriveRestAPI_v3.Models
{
    public class GoogleDriveFiles
    {
          public string Id { get; set; }
          public string Name { get; set; }
          public long? Size { get; set; }
          public long? Version { get; set; }
          public DateTime? CreatedTime { get; set; }
          public IList<string> Parents { get; set; }
    }
}

Step 4 (Repository): 
After that, create an another class (Name: GoogleDriveFilesRepository.csunder this same Model folder. Please Copy & Paste this below code.

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

namespace GoogleDriveRestAPI_v3.Models
{
    public class GoogleDriveFilesRepository
    {
        public static string[] Scopes = { Google.Apis.Drive.v3.DriveService.Scope.Drive };
        public static Google.Apis.Drive.v3.DriveService GetService_v3()
        {
            UserCredential credential;
            using (var stream = new FileStream(@"D:\client_secret.json", FileMode.Open, FileAccess.Read))
            {
                String FolderPath = @"D:\";
                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.
            Google.Apis.Drive.v3.DriveService service = new Google.Apis.Drive.v3.DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "GoogleDriveRestAPI-v3",
            });

            return service;
        }

        public static Google.Apis.Drive.v2.DriveService GetService_v2()
        {
            UserCredential credential;
            using (var stream = new FileStream(@"D:\client_secret.json", FileMode.Open, FileAccess.Read))
            {
                String FolderPath = @"D:\";
                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.
            Google.Apis.Drive.v2.DriveService service = new Google.Apis.Drive.v2.DriveService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "GoogleDriveRestAPI-v2",
            });
            return service;
        }

        public static List<GoogleDriveFiles> GetContainsInFolder(String folderId)
        {
            List<string> ChildList = new List<string>();
            Google.Apis.Drive.v2.DriveService ServiceV2 = GetService_v2();
            ChildrenResource.ListRequest ChildrenIDsRequest = ServiceV2.Children.List(folderId);
            do
            {
                ChildList children = ChildrenIDsRequest.Execute();

                if (children.Items != null && children.Items.Count > 0)
                {
                    foreach (var file in children.Items)
                    {
                        ChildList.Add(file.Id);
                    }
                }
                ChildrenIDsRequest.PageToken = children.NextPageToken;

            } while (!String.IsNullOrEmpty(ChildrenIDsRequest.PageToken));

            //Get All File List
            List<GoogleDriveFiles> AllFileList = GetDriveFiles();
            List<GoogleDriveFiles> Filter_FileList = new List<GoogleDriveFiles>();

            foreach (string Id in ChildList)
            {
                Filter_FileList.Add(AllFileList.Where(x => x.Id == Id).FirstOrDefault());
            }
            return Filter_FileList;
        }

        public static void CreateFolder(string FolderName)
        {
            Google.Apis.Drive.v3.DriveService service = GetService_v3();

            var FileMetaData = new Google.Apis.Drive.v3.Data.File();
            FileMetaData.Name = FolderName;
            FileMetaData.MimeType = "application/vnd.google-apps.folder";

            Google.Apis.Drive.v3.FilesResource.CreateRequest request;

            request = service.Files.Create(FileMetaData);
            request.Fields = "id";
            var file = request.Execute();
            Console.WriteLine("Folder ID: " + file.Id);
        }
        public static void FileUploadInFolder(string folderId, HttpPostedFileBase file)
        {
            if (file != null && file.ContentLength > 0)
            {
                Google.Apis.Drive.v3.DriveService service = GetService_v3();

                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()
                {
                    Name = Path.GetFileName(file.FileName),
                    MimeType = MimeMapping.GetMimeMapping(path),
                    Parents = new List<string>
                    {
                        folderId
                    }
                };

                Google.Apis.Drive.v3.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();
                }
                var file1 = request.ResponseBody;
            }
        }
        public static List<GoogleDriveFiles> GetDriveFiles()
        {
            Google.Apis.Drive.v3.DriveService service = GetService_v3();

            // Define parameters of request.
            Google.Apis.Drive.v3.FilesResource.ListRequest FileListRequest = service.Files.List();
            FileListRequest.Fields = "nextPageToken, files(createdTime, id, name, size, version, trashed, parents)";

            // List files.
            IList<Google.Apis.Drive.v3.Data.File> files = FileListRequest.Execute().Files;
            List<GoogleDriveFiles> FileList = new List<GoogleDriveFiles>();

            if (files != null && files.Count > 0)
            {
                foreach (var file in files)
                {
                    GoogleDriveFiles File = new GoogleDriveFiles
                    {
                        Id = file.Id,
                        Name = file.Name,
                        Size = file.Size,
                        Version = file.Version,
                        CreatedTime = file.CreatedTime,
                        Parents = file.Parents
                    };
                    FileList.Add(File);
                }
            }
            return FileList;
        }

        public static void FileUpload(HttpPostedFileBase file)
        {
            if (file != null && file.ContentLength > 0)
            {
                Google.Apis.Drive.v3.DriveService service = GetService_v3();

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

                Google.Apis.Drive.v3.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();
                }
            }
        } 
    }
}      

Step 5 (Controller): Add a controller class (HomeController.cs) under this controller folder.

                        

Copy & Paste this code within this controller:

using GoogleDriveRestAPI_v3.Models;
using System;
using System.Web;
using System.Web.Mvc;

namespace GoogleDriveRestAPI_v3.Controllers
{
    public class HomeController : Controller
    {
        [HttpGet]
        public ActionResult GetGoogleDriveFiles()
        {
            return View(GoogleDriveFilesRepository.GetDriveFiles());
        }

        [HttpGet]
        public ActionResult GetContainsInFolder(string folderId)
        {
            return View(GoogleDriveFilesRepository.GetContainsInFolder(folderId));
        }

        [HttpPost]
        public ActionResult CreateFolder(String FolderName)
        {
            GoogleDriveFilesRepository.CreateFolder(FolderName);
            return RedirectToAction("GetGoogleDriveFiles");
        }

        [HttpPost]
        public ActionResult UploadFile(HttpPostedFileBase file)
        {
            GoogleDriveFilesRepository.FileUpload(file);
            return RedirectToAction("GetGoogleDriveFiles");
        }

        [HttpPost]
        public ActionResult FileUploadInFolder(GoogleDriveFiles FolderId, HttpPostedFileBase file)
        {
            GoogleDriveFilesRepository.FileUploadInFolder(FolderId.Id, file);
            return RedirectToAction("GetGoogleDriveFiles");
        }
    }
}

Step 6 (View): We need to create two views, the First view for showing the root directory contains Google drive & second view is for showing inner file & folder structure of a particular folder.

View 1: Add a View (View Name: GetGoogleDriveFiles.cshtml) of GetGoogleDriveFiles action method.

Copy & Paste this code within this View:

@model IEnumerable<GoogleDriveRestAPI_v3.Models.GoogleDriveFiles>
@{
    ViewBag.Title = "Google Drive API v3 - ASP.NET MVC 5 [Everyday Be Coding]";
}
<h2 class="imagetable">Google Drive API v3 - [Root Directory]</h2>

<style type="text/css">
    table.imagetable {
        font-family: verdana,arial,sans-serif;
        font-size: 11px;
        color: #333333;
        border-width: 1px;
        border-color: #999999;
        border-collapse: collapse;
    }

        table.imagetable th {
            background: #b5cfd2 url('cell-blue.jpg');
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #999999;
        }

        table.imagetable td {
            /*background: #dcddc0 url('cell-grey.jpg');*/
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #999999;
        }
</style>

<center>
    <div style="width:100%;">
        <table class="imagetable">
            <tr>
                <td>
                    @using (Html.BeginForm("CreateFolder", "Home", FormMethod.Post))
                    {
                        <p>
                            Folder Name :<input type="text" name="FolderName" id="txtFolderName" style="align-content:center" />
                            <input type="submit" class="CreateFolder" value="Create Folder" style="align-content:center" />
                        </p>
                    }
                </td>
                <td>
                    @using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
                    {
                        <label>File Upload in Root :</label>
                        <input type="file" name="file" id="file" style="width:176px;" />
                        <input type="submit" value="Upload" />
                    }
                </td>
            </tr>
        </table>
    </div>

    <br />

    <table class="imagetable">
        <tr id="header">
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Size)
            </th>
            <th>
                Type
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Version)
            </th>
            <th>
                Created Time
            </th>
            <th>
                Upload
            </th>
        </tr>

        @if (Model.Count() > 0)
        {
            foreach (var item in Model)
            {
                if (item.Parents[0] == "0ANNR3nwrf6gUUk9PVA")
                {
                    <tr>
                        @{
                            string FileSize = string.Empty;
                            string Type = string.Empty;
                            if (@item.Size != null)
                            {
                                long? KiloByte = @item.Size;
                                FileSize = KiloByte + " bytes";
                            }
                        }
                        <td>
                            @if (@item.Size == null)
                            {
                                <a href="@Url.Action("GetContainsInFolder", "Home", new { folderId = item.Id })">@item.Name</a>
                            }
                            else
                            { @item.Name }
                        </td>
                        <td>
                            @FileSize
                        </td>
                        <td>
                            @{
                            if (FileSize == string.Empty) { Type = "Folder"; }
                            else { Type = "File"; }
                             }
                            @Type
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Version)
                        </td>
                        <td>
                            @string.Format("{0: MM/dd/yyyy}", Convert.ToDateTime(Html.DisplayFor(modelItem => item.CreatedTime).ToString()))
                        </td>

                        <td>
                            @if (FileSize == string.Empty)
                            {
                                using (Html.BeginForm("FileUploadInFolder", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
                                {
                                    <input type="hidden" name=Id value="@item.Id">
                                    <input type="file" name="file" id="file" style="width:176px;" />
                                    <input type="submit" value="Upload" />
                                }
                            }
                        </td>
                    </tr>
                }
            }
        }
        else
        {
            <tr> <td colspan="6">No Records found</td> </tr>
        }
    </table>
</center>


View 2: Add a View (View Name: GetContainsInFolder.cshtml) of GetContainsInFolder() action method.

Copy & Paste this code within this View:

@model IEnumerable<GoogleDriveRestAPI_v3.Models.GoogleDriveFiles>

<style type="text/css">
    table.imagetable {
        font-family: verdana,arial,sans-serif;
        font-size: 11px;
        color: #333333;
        border-width: 1px;
        border-color: #999999;
        border-collapse: collapse;
    }

        table.imagetable th {
            background: #b5cfd2 url('cell-blue.jpg');
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #999999;
        }

        table.imagetable td {
            /*background: #dcddc0 url('cell-grey.jpg');*/
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #999999;
        }
</style>
<center>
    <br><br>
    @if (Model.Count() > 0)
    {
        <table class="imagetable">
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Name)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Size)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Version)
                </th>
                <th>
                    Created Time
                </th>
            </tr>

            @foreach (var item in Model)
            {
                        string FileSize = string.Empty;
                        string Type = string.Empty;
                        if (@item.Size != null)
                        {
                            long? KiloByte = @item.Size;
                            FileSize = KiloByte + " bytes";
                        }
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Name)
                    </td>
                    <td>
                        @FileSize
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Version)
                    </td>
                    <td>
                        @string.Format("{0: MM/dd/yyyy}", Convert.ToDateTime(Html.DisplayFor(modelItem => item.CreatedTime).ToString()))
                    </td>
                </tr>
            }
        </table>
    }
    else
    {
        <table class="imagetable">
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Name)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Size)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Version)
                </th>
                <th>
                    Created Time
                </th>
            </tr>
        <tr><td colspan="4">No records found</td></tr>
        </table>
    }

   @Html.ActionLink("Back", "GetGoogleDriveFiles")
</center>

Step 7 : Change the default action method name 'Index' to  'GetGoogleDriveFiles'.

using System.Web.Mvc;
using System.Web.Routing;

namespace GoogleDriveRestAPI_v3
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "GetGoogleDriveFiles", id = UrlParameter.Optional }
            );
        }
    }
}

Thank you for reading this blogs. 
Please subscribe my YouTube Channel & don't forget to like and share. 

YouTube :https://goo.gl/rt4tHH
Facebook :https://goo.gl/hgpQsh
Twitter :https://goo.gl/nUwGnf

Comments

  1. this example not work on iis , it make iis stop, do you have solution

    ReplyDelete

Post a Comment

Popular posts from this blog

Cloud Storage Access through API  - Advanced Developer Guide - C#  1. Google Drive API - Enable & Get Client Credentials for Application 2. Google Drive API - Uploading, Viewing, Downloading & Deleting Files 3. Google Drive API - Create folder, Upload file to folder, Show folder Content. 4. Google Drive API - How to Move & Copy Files Between Folders. 5. Google Drive API - How to Share & Set Permission of File/Folders. 6. Google Drive API - View Share Users Permission Details. 7. Google Picker API - Viewing, Uploading, Downloading, Sharing. ASP.NET  MVC Tutorial - Advanced Developer Guide - C#  How to Export Razor View to Excel file (Without using Third-Party Library). Excel Development using EPPlus Library Beginners Guide - C# 1. Create an Excel File using EPPlus .Net Library. 2. Apply Cell text and Background Color in Excel Sheet. 3. Apply Cell Border Style in Excel Sheet. 4. Apply Cell Text Alignment, Row Height, Column Width in Excel Sheet

Google Drive API using JavaScript | Full Project - Overview

Setup Google Developer Console for Google Drive API Applications using J...