asp.net-core - ASP.NET Core Web API 中的上传文件百分比
问题描述
我开发了一个 ASP.NET 核心 web api 应用程序来将文件从一个路径上传到另一个路径。我通过邮递员测试api。我想在上传文件时显示上传文件的百分比。如何在 Web API 上做到这一点。任何帮助表示赞赏。
[HttpPost]
public IActionResult PostUploadFiles([FromForm] List<IFormFile> postedFiles)
{
try
{
string wwwPath = this.Environment.WebRootPath;
string contentPath = this.Environment.ContentRootPath;
string path = Path.Combine(this.Environment.ContentRootPath, "Uploads");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
List<string> uploadedFiles = new List<string>();
foreach (IFormFile postedFile in postedFiles)
{
string fileName = Path.GetFileName(postedFile.FileName);
using (FileStream stream = new FileStream(Path.Combine(path, fileName), FileMode.Create))
{
postedFile.CopyTo(stream);
FileInfo file = new FileInfo(Path.Combine(path, fileName));
long size = file.Length / 1024;
uploadedFiles.Add(fileName);
}
}
return new ObjectResult("File has been successfully uploaded") { StatusCode = Convert.ToInt32(HttpStatusCode.Created)};
}
catch(Exception ex)
{
return new ObjectResult("File has not been uploaded") { StatusCode = Convert.ToInt32(HttpStatusCode.BadRequest) };
}
}
解决方案
据我所知,如果您想获取有关当前请求的流程,您应该编写代码来计算当前读取的字节数和总字节数,并使用流程变量来存储流程百分比。然后你可以写一个新的 web api 方法来返回这个过程。
更多细节,您可以参考以下代码:
将静态变量 Progress 添加到 startup.cs。注意:这不是使用静态变量的最佳主意(尤其是当您同时有多个活动上传会话时)
public class Startup
{
public static int Progress { get; set; }
public void ConfigureServices(IServiceCollection services){...}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env){...}
}
API控制器:
public class UploaderController : Controller
{
private IHostingEnvironment Environment;
public UploaderController(IHostingEnvironment hostingEnvironment)
{
this.Environment = hostingEnvironment;
}
[HttpPost]
public async Task<IActionResult> Index([FromForm] List<IFormFile> postedFiles)
{
Startup.Progress = 0;
long totalBytes = postedFiles.Sum(f => f.Length);
long totalReadBytes = 0;
string path = Path.Combine(this.Environment.ContentRootPath, "Uploads");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
foreach (IFormFile source in postedFiles)
{
byte[] buffer = new byte[16 * 1024];
string fileName = Path.GetFileName(source.FileName);
using (FileStream output = System.IO.File.Create(Path.Combine(path, fileName)))
using (Stream input = source.OpenReadStream())
{
int readBytes;
while ((readBytes = input.Read(buffer, 0, buffer.Length)) > 0)
{
await output.WriteAsync(buffer, 0, readBytes);
totalReadBytes += readBytes;
Startup.Progress = (int)((float)totalReadBytes / (float)totalBytes * 100.0);
await Task.Delay(100); // It is only to make the process slower, you could delete this line
}
}
}
return new ObjectResult("File has been successfully uploaded") { StatusCode = Convert.ToInt32(HttpStatusCode.Created) };
}
[HttpPost]
public ActionResult Progress()
{
return this.Content(Startup.Progress.ToString());
}
}
结果:
发送文件:
获取过程:
推荐阅读
- arangodb - 如何在 ArangoDB 中返回文档之前在文档中添加/删除属性?
- angular - rxJS 的 debounceTime 在本地工作时工作,但在构建后它没有按预期工作
- javascript - 如何检查字符串是否与 Mongoose 的数组元素匹配
- python - 为 Ximea 相机设置下采样
- c - 在没有 arduino 的情况下为 atmega32 创建新的电子纸库
- powerbi - 如何平均一列值,同时排除另一列中包含某个值的行?PowerBi
- leaflet - Leaflet Routing Machine 上的语言未切换为法语
- python - 如何在 jupyter 笔记本(VSCode + Python 扩展)中隐藏单元格输出?
- javascript - 当 Share Point 2013 列表中的列为空时,如何隐藏 Null 文本?
- spring-boot - 在 spring-boot 2.1.9.release 中寻找匹配的 CachePublicMetrics