有什么方法可以使用 .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 管道、容器...)
是否可以使用 .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 管道、容器...)