Reputation: 148
I'm building a file upload web application using ASP.NET Core 6 and I would like the user to be able to confirm whether or not to overwrite an existing file. The application allows for multiple file uploads
This is my form:
<form method="POST" enctype="multipart/form-data">
<input type="file" multiple name="files">
<button type="submit" class="btn custom-button">Upload Files</button>
</form>
This is the controller action:
[HttpPost]
public async Task<IActionResult> UploadFiles(IEnumerable<IFormFile> files, string folders)
{
foreach (var file in files)
{
string trimmedFileName = String.Concat(file.FileName.Where(c =>!Char.IsWhiteSpace(c)));
var filePath = Path.Combine(folders, trimmedFileName);
if (System.IO.File.Exists(filePath))
{
ViewBag.Error = $"File {trimmedFileName} already exists on the server";
this.Redirect("UploadFiles");
}
using var filestream = System.IO.File.Create(filePath);
await file.CopyToAsync(filestream);
}
}
I have simplified the above code so as not too add too much detail
I have tried AJAX calls to stop the POST request and add some logic but I don't seem to be able to access the folder on the server to even check if the file already exists
$("#uploadForm").submit(function(e){
e.preventDefault();
let files = $(".form-control-file")[0].files;
for (let i = 0; i < files.length; i++){
let url = $("#filePathUrl").val() + "/" + files[i].name;
if(url){
$.ajax({
url: url,
type: 'HEAD',
error: function(){
alert(files[i].name + " exists!");
},
success: function(){
alert(files[i].name + " does not exist on server");
I have simplified and removed closing braces from the above code to keep things simple
Upvotes: 1
Views: 794
Reputation: 11889
Your POST to upload the file could return a 409 Conflict status if a file already exists. The UI would then detect this on first posting, and show a popup. If the user selects 'continue', then the POST could include a query parameter to say the user has confirmed the OK is allowed. Something like this:
[HttpPost]
public async Task<IActionResult> UploadFiles(bool? allowOverwrite, IEnumerable<IFormFile> files, string folders)
{
foreach (var file in files)
{
string trimmedFileName = String.Concat(file.FileName.Where(c => !Char.IsWhiteSpace(c)));
var filePath = Path.Combine(folders, trimmedFileName);
if (!allowOverwrite.GetDefaultValue() && System.IO.File.Exists(filePath)) < ---
{
ViewBag.Error = $"File {trimmedFileName} already exists on the server";
return Conflict(); < ---
}
using var filestream = System.IO.File.Create(filePath);
await file.CopyToAsync(filestream);
}
}
Upvotes: 0
Reputation: 2162
Here's what you can do,
Lets move to code
JS
function processFiles(confirmOverwrite = false){
const files = $(".form-control-file")[0].files;
const formData = new FormData();
files.forEach(file => formData,append('files[]', file));
const folderName = 'Uploads';
const url = $("#filePathUrl").val();
$.ajax({
url: url+'?folders='+folderName+'&confirmOverwrite='+confirmOverwrite,
type: 'POST',
data: formData,
processData: false,
success: (response) =>{
if(response.Status){
alert('Files uploadedn successfully');
}
else{
if(response.Message){
if(confirm(response.Message + ' files already exist. Do you want to overwrite these?')){
processFiles(true);
}
else{
alert('Files not uploaded');
}
}
}
},
error: (a,b,c) => {
console.error({a,b,c});
}
});
}
$("#uploadForm").submit(function(e){
e.preventDefault();
processFiles(false);
});
Controller
[HttpPost]
public async Task<IActionResult> UploadFiles(IEnumerable<IFormFile> files, string folders, bool confirmOverwrite = false)
{
var existingFiles = new List<string>();
var filesToBeSaved = new List<(IFormFile file, string filePath)>();
foreach (var file in files)
{
string trimmedFileName = file.FileName.Replace(" ", "");
var filePath = Path.Combine(folders, trimmedFileName);
if (System.IO.File.Exists(filePath) && !confirmOverwrite)
{
existingFiles.Add(file.FileName + "("+ trimmedFileName + ")");
}
else
{
filesToBeSaved.Add((file, filePath));
}
}
if (existingFiles.Any())
{
return Json(new { Status = false, Message = string.Join(", ", existingFiles) });
}
else
{
foreach (var (file, filePath) in filesToBeSaved)
{
using var filestream = System.IO.File.Create(filePath);
await file.CopyToAsync(filestream);
}
return Json(new { Status = true, Message = "Success" });
}
}
Upvotes: 1