首页 > 解决方案 > 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) };
    }

}

标签: asp.net-corepostmanasp.net-core-webapi

解决方案


据我所知,如果您想获取有关当前请求的流程,您应该编写代码来计算当前读取的字节数和总字节数,并使用流程变量来存储流程百分比。然后你可以写一个新的 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());
    }

}

结果:

发送文件:

在此处输入图像描述

获取过程:

在此处输入图像描述


推荐阅读