Home > Mobile >  Is there any way to upload a folder(have subfolders also) instead of file using .netcore web api
Is there any way to upload a folder(have subfolders also) instead of file using .netcore web api

Time:09-30

Is it possible to upload the entire folder with same folder structure using .netcore webapi. I know we can zip and upload, then unzip, just wondering for alternative way to upload as it is instead of zipping

Currently i have updated the controller as below, this logic doesnot consider folders for upload

    private async Task<bool> Import()
    {
        bool isSaveSuccess = false;
        string fileName;
        var files = Request.Form.Files;
        foreach (var file in files)
        {
            try
            {
                var extn = "."   file.FileName.Split('.')[file.FileName.Split('.').Length - 1];
                fileName = file.FileName   DateTime.Now.Ticks   extn;
                //fileName = Path.Combine(file.FileName, DateTime.Now.Ticks   extn);

                var pathBuilt = Path.Combine(Directory.GetCurrentDirectory(), "Upload\\files1");

                if (!Directory.Exists(pathBuilt))
                {
                    Directory.CreateDirectory(pathBuilt);
                }

                var path = Path.Combine(Directory.GetCurrentDirectory(), "Upload\\files1", fileName);

                using (var stream = new FileStream(path, FileMode.Create))
                {
                    await file.CopyToAsync(stream);
                }
                isSaveSuccess = true;
            }
            catch
            {
                _logger.LogError("Request failed: "   "err");

            }
        }
        return isSaveSuccess;
    }

CodePudding user response:

Yes, it should be possible. Have a look at webkitdirectory property: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory

This will let you select one or more folders, so you can iterate over the inner contents of the users selection. As you can see, this is a "native" feature and not limited to asp.net or c# in any way.

<input type="file" id="files" name="files" webkitdirectory multiple />
<ul id="listing"></ul>
document.getElementById("filepicker").addEventListener("change", function(event) {
  let output = document.getElementById("listing");
  let files = event.target.files;

  for (let i=0; i<files.length; i  ) {
    let item = document.createElement("li");
    item.innerHTML = files[i].webkitRelativePath;
    output.appendChild(item);
  };
}, false);

As you can see from the demo code, you can get the relative path by calling .webkitRelativePath, so yit should be no problem to recreate the folder structure on your target.

Be aware, that this feature is not natively available on Internet Explorer and Firefox versions on android below 50.

Update for saving files with subfolders

Here is a bare minimum example of uploading taking any number of uploaded form files and saving them to disk, while keeping the relative folder structure.

First change your controllers constructor to get a your current environment in:

private readonly IWebHostEnvironment _env;
public HomeController(IWebHostEnvironment environment)
{
   _env = environment;
}

Then amend your upload logic accordingly:

[HttpPost]
public async Task<IActionResult> Upload([FromForm] IFormFileCollection files)
{
   //target in wwwroot for static files
   string targetFolder = Path.Combine(_env.WebRootPath, "uploads");
   foreach (IFormFile file in files)
   {
      if (file.Length <= 0) continue;

      //fileName is the the fileName including the relative path
      string path = Path.Combine(targetFolder, file.FileName);

      //check if folder exists, create if not
      var fi = new FileInfo(path);
      fi.Directory?.Create();

      //copy to target
      using var fileStream = new FileStream(path, FileMode.Create);
      await file.CopyToAsync(fileStream);
   }
   return View("Index");
}

This will result to your folder and all its subfolders being saved into your wwwroot/uploads/ folder inside your application:

wwwroot/
|
|-uploads
        |-MyFolder
                 |- File1.jpg
                 |- File2.jpg
                 |- MyFolder2
                            |- File3.jpg

I'd recommend saving them somewhere different though, because redeploying might clean out the application folder first, depending on your deployment strategy (xcopy, github actions, azure pipelines, containers ...)

  • Related