locked
File Unable To Be Differentiated Whether New or Duplicated. RRS feed

  • Question

  • User-846837922 posted

    I have a program that should be able to identify when a new or existing file is uploaded to the Google Drive. It works based on identifying that if there is already an existing file, then the user will be redirected to the upload page again otherwise, the user will be alerted that file is successful. I have been trying to wrap around how to get by with the logic but the problem now is that the program will accept the files irregardless if it is new or existing. 

    My code for the fileupload method.

      public static bool FileUpload(HttpPostedFileBase file)
            {
                if (file != null && file.ContentLength > 0)
                {
                    DriveService service = GetService();
    
                   string path = Path.Combine(HttpContext.Current.Server.MapPath("~/GoogleDriveFiles"),Path.GetFileName(file.FileName));
                    file.SaveAs(path);
    
              //      HashGenerator(path);  
                    if(compareHash(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 FileStream(path, FileMode.Open))
                        {
                            request = service.Files.Create(FileMetaData, stream, FileMetaData.MimeType);
                            request.Fields = "id";
                            request.Upload();
                        }
    
                        return true;
                    }
                    return false;              
                }
                return false;
            } 
    
            public static bool compareHash(string path)
            {
                
                DriveService service = GetService();
                FilesResource.ListRequest FileListRequest = service.Files.List();
                IList<Google.Apis.Drive.v3.Data.File> files = FileListRequest.Execute().Files;
                List<GoogleDriveFiles> FileList = new List<GoogleDriveFiles>();
    
                foreach (var file in files)
                {
                    if (file.Equals(path))
                    {
                        return false;
                    
                    }
                    return true;
                }
               return true;
               
            }
            

    This is my code for the file upload controller. 

            [HttpPost]
            public JsonResult UploadFile(HttpPostedFileBase file)
            {
                bool kk = GoogleDriveFilesRepository.FileUpload(file);
                return Json(kk, JsonRequestBehavior.AllowGet);
            }

    This is my razor code for the file upload.

      <script>
                    $('#fileUpload').click(function (e) {
    
                        if ($('#file').val() === "") {
                            Swal.fire({
                                title: 'Nothing',
                                text: 'No file selected',
                                type: 'error',
                                confirmButtonText: 'Again!!',
                                timer: 4000
                            });
                        }
    
                        else {
                                event.preventDefault();
                                var formData = new FormData($('form')[0]);
    
                                $.ajax({
                                    url: "/Home/UploadFile",
                                    type: 'Post',
                                    success: function (result) {
                                        if (result) {
                                            Swal.fire({
                                                title: 'Wait awhile...',
                                                text: 'File will be uploaded shortly',
                                                type: 'success',
                                                confirmButtonText: 'Okay, cool',
                                                timer: 4000
                                            })
                                            location.href = "/Home/GetGoogleDriveFiles";
                                           
                                        } else {
                                            Swal.fire({
                                                title: 'OOps',
                                                text: 'File unable to be uploaded shortly',
                                                type: 'error',
                                                confirmButtonText: 'Okay, then',
                                                timer: 4000
                                            })
                                            location.href = "/Home/GoogleDriveFiles";
                                         
                                        }
                                    },
                                    data: formData,
                                    cache: false,
                                    contentType: false,
                                    processData: false
                                });
                        }
                    }
                );
            </script>

    I am not too sure which part of my logic is not able to distinguish the file if it already exists or not. 

    Thursday, October 24, 2019 12:11 PM

Answers

  • User-846837922 posted

    I finally managed to got it working. 

    //file Upload to the Google Drive.
            public static bool FileUpload(HttpPostedFileBase file)
            {
                if (file != null && file.ContentLength > 0)
                {
                    DriveService service = GetService();
    
                   string path = Path.Combine(HttpContext.Current.Server.MapPath("~/GoogleDriveFiles"),Path.GetFileName(file.FileName));
                   file.SaveAs(path);
    
                    var hash = HashGenerator(path);
    
                   if(!CompareHash(hash))
                    {
                        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 FileStream(path, FileMode.Open))
                        {
                            request = service.Files.Create(FileMetaData, stream, FileMetaData.MimeType);
                            request.Fields = "id";
                            request.Upload();
                        }
                       
                        return true; //determine if file is uploaded or not
                    }
                    return false;   //affects message                 
                }
               return false;
               
            }
         public static string HashGenerator(string path)
            {
                using (var md5 = MD5.Create())
                {
                    using (var stream = new FileStream(path, FileMode.Open))
                    {
                        return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower();
                    }
                }
            }
    
            public static bool CompareHash (string hash)
            {
                var service = GetService();
                var fileListRequest = service.Files.List();
                fileListRequest.Fields = "*";
                var files = fileListRequest.Execute().Files;
    
                foreach(var file in files)
                {
                    if(file.Md5Checksum.Equals(hash))
                    {
                        return true;
                    }
    
                }
                return false;
            }

    Thanks for the help and advise. I really appreciate it.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, October 25, 2019 6:16 PM

All replies

  • User665608656 posted

    Hi JasonPhang,

    According to your description, the real code to determine whether a file is duplicated is in the comparehash method in the controller.

    In the comparehash method, you can't directly compare a file path to files in Google drive.

    After several queries, I suggest that you use the file name method to verify in the comparehash method. You can refer to the following links:

    https://stackoverflow.com/a/54819195

    Search files on Google Drive with C#

    How To Search Files On Google Drive Progamatically From .NET Using Drive API

    Best Regards,

    YongQing.

    Friday, October 25, 2019 5:48 AM
  • User-846837922 posted

    I tried to follow the third link or query but I am not too sure what to return and how to proceed from there since that tutorial is a win form and mine is website based, I am unsure what to write for the controller and what to return in this code block..

      public Google.Apis.Drive.v3.Data.File SearchFiles(string query)
            {
                DriveService service = GetService();
                FilesResource.ListRequest fileListRequest = service.Files.List();
                fileListRequest.Q = query;
    
                fileListRequest.Fields = "nextPageToken, files(id,name,md5Checksum,mimeType)";
    
                IList<Google.Apis.Drive.v3.Data.File> files = fileListRequest.Execute().Files;
                List<GoogleDriveFiles> FileList = new List<GoogleDriveFiles>();
                var result = fileListRequest.Execute();
    
                if(result.Files.Count > 0)
                {
                    foreach(Google.Apis.Drive.v3.Data.File file in result.Files)
                    {
                        if(file.Id.Equals(query))
                        {
                           //`not to sure what to return although i wanted to return like 
                           //a bool false?
                        }
                        
                    }
                }
    
            }

    Friday, October 25, 2019 6:45 AM
  • User665608656 posted

    Hi JasonPhang,

    The logic here is the same as the code you used before. You just change the method of comparison, and return the boolean value here.

          public bool SearchFiles(string query)
            {
                DriveService service = GetService();
                FilesResource.ListRequest fileListRequest = service.Files.List();
                fileListRequest.Q = query;
    
                fileListRequest.Fields = "nextPageToken, files(id,name,md5Checksum,mimeType)";
    
                IList<Google.Apis.Drive.v3.Data.File> files = fileListRequest.Execute().Files;
                List<GoogleDriveFiles> FileList = new List<GoogleDriveFiles>();
                var result = fileListRequest.Execute();
    
                if (result.Files.Count > 0)
                {
                    foreach (Google.Apis.Drive.v3.Data.File file in result.Files)
                    {
                        if (file.Id.Equals(query))
                        {
                            return false; // cannot upload
                        }
    
                    }
                }
                return true;
    
            }

    Best Regards,

    YongQing.

    Friday, October 25, 2019 7:58 AM
  • User-846837922 posted

    I tried to implement a filter to not allow value of virtual to be uploaded but still there is no difference. I just do not know how to pass the value of the logic to the controller to accept the value passed. It is now like if in the controller, i pass true, it accepts true , if false, then false. it is not verifying the value of the bool from this code block. 

            public static bool SearchFiles(string query)
            {
                DriveService service = GetService();
                //   FilesResource.ListRequest fileListRequest = service.Files.List();
                var request = service.Files.List();
                request.Q = " name contains 'Virtual'";
                query = request.Q;
                request.Fields = "nextPageToken, files(id,name,mimeType)";
                var result = request.Execute();
                if (result.Files.Count > 0)
                {
                    foreach(var file in result.Files)
                    {
                        if(file.Name.Equals(query))
                        {
                            //`not to sure what to return although i wanted to return like 
                            //a bool false?
                            return false;
                        }
                        return true;
                    }
                }
               return false;
            }
    

    Friday, October 25, 2019 10:23 AM
  • User-846837922 posted

    I finally managed to got it working. 

    //file Upload to the Google Drive.
            public static bool FileUpload(HttpPostedFileBase file)
            {
                if (file != null && file.ContentLength > 0)
                {
                    DriveService service = GetService();
    
                   string path = Path.Combine(HttpContext.Current.Server.MapPath("~/GoogleDriveFiles"),Path.GetFileName(file.FileName));
                   file.SaveAs(path);
    
                    var hash = HashGenerator(path);
    
                   if(!CompareHash(hash))
                    {
                        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 FileStream(path, FileMode.Open))
                        {
                            request = service.Files.Create(FileMetaData, stream, FileMetaData.MimeType);
                            request.Fields = "id";
                            request.Upload();
                        }
                       
                        return true; //determine if file is uploaded or not
                    }
                    return false;   //affects message                 
                }
               return false;
               
            }
         public static string HashGenerator(string path)
            {
                using (var md5 = MD5.Create())
                {
                    using (var stream = new FileStream(path, FileMode.Open))
                    {
                        return BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", "").ToLower();
                    }
                }
            }
    
            public static bool CompareHash (string hash)
            {
                var service = GetService();
                var fileListRequest = service.Files.List();
                fileListRequest.Fields = "*";
                var files = fileListRequest.Execute().Files;
    
                foreach(var file in files)
                {
                    if(file.Md5Checksum.Equals(hash))
                    {
                        return true;
                    }
    
                }
                return false;
            }

    Thanks for the help and advise. I really appreciate it.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, October 25, 2019 6:16 PM