有什么方法可以使用 .netcore web api 上传文件夹(也有子文件夹)而不是文件

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

是否可以使用 .netcore webapi 上传具有相同文件夹结构的整个文件夹。我知道我们可以压缩和上传,然后解压缩,只是想知道其他上传方式而不是压缩

目前我已经更新控制器如下,这个逻辑不考虑上传文件夹

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

是的,应该可以。看看 webkitdirectory 属性: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory

这将使您 select 一个或多个文件夹,因此您可以遍历用户 selection 的内部内容。如您所见,这是一个“本机”功能,并不局限于 asp.net 或 c#。

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

从演示代码中可以看出,您可以通过调用.webkitRelativePath获取相对路径,因此在您的目标上重新创建文件夹结构应该没有问题。

请注意,android 50 以下的 Internet Explorer 和 Firefox 版本本身不提供此功能。

使用子文件夹保存文件的更新

这里是上传任意数量的表单文件并将它们保存到磁盘的最小示例,同时保持相关文件夹结构。

首先更改您的控制器构造函数以获取您当前的环境:

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

然后相应地修改您的上传逻辑:

[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");
}

这将导致您的文件夹及其所有子文件夹被保存到应用程序内的 wwwroot/uploads/ 文件夹中:

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

我建议将它们保存在不同的地方,因为重新部署可能会首先清除应用程序文件夹,具体取决于您的部署策略(xcopy、github 操作、azure 管道、容器...)