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,buffer.Length)) > 0)
                {
                    await output.WriteAsync(buffer,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());
    }

}

结果:

发送文件:

enter image description here

获取流程:

enter image description here