1

I have developed an ASP.NET core web api application to upload files from one path to other path. I test the api through postman. I would like to display percentage of file uploaded while uploading a file. How to do it on Web API. Any help is appreciated.

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

}
Divyang Desai
  • 7,483
  • 13
  • 50
  • 76

1 Answers1

1

As far as I know, if you want to get the process about your current request, you should write the codes to calculate current read bytes with total bytes and use a process variable to store the process percent. Then you could write a new web api method to return the process.

More details, you could refer to below codes:

Add static variable Progress into startup.cs. Notice:This is not the best idea to use a static variable (especially when you have more than one active uploading session at the same time)

public class Startup
{
    public static int Progress { get; set; }
    public void ConfigureServices(IServiceCollection services){...}
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env){...}
}

API controller:

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

}

Result:

Send file:

enter image description here

Get process:

enter image description here

PajLe
  • 791
  • 1
  • 7
  • 21
Brando Zhang
  • 22,586
  • 6
  • 37
  • 65