简体   繁体   中英

Asp.net core file uploads reporting progress back to the front end

I am currently uploading files using an form post method I see many examples but not for IFromFile usuage I was wondering how one would report progress. Im using asp.net core 3.1

I am posting my files using an a multipart form to post the files.

<form  method="post" asp-controller="FileAttachments"  asp-action="UploadFiles" enctype="multipart/form-data">
 <div asp-validation-summary="ModelOnly" class="text-danger"></div>
 <div class="form-group">
    <input type="file" id="FormFile" multiple="multiple" class="btn-primary float-left" name="FormFile">
    <input type="submit" id="btnUpload" class="btn-primary float-right"    value="Upload Files" />
 </div>
And here is my controller method
[HttpPost] public async Task<IActionResult> UploadFiles(List<IFormFile> FormFile) { Int32.TryParse(TempData.Peek("CaseId").ToString(), out int resultCaseId); long size = FormFile.Sum(f => f.Length); FileAttachments.FileAttachmentTypes fileAttachmentType = FileAttachments.FileAttachmentTypes.None; foreach (var fileAttachments in FormFile) { if (fileAttachments.Length > 0) { string filePath = Path.Combine(hostingEnvironment.WebRootPath, "Uploads"); var tennantId = GetCurrentTennantId().Result; var settings = _context.SystemSetup.FirstOrDefault().UploadFolderPath; string uniqueFilename = Guid.NewGuid().ToString() + "_" + fileAttachments.FileName; string savedFileName = Path.Combine(filePath, uniqueFilename); await fileAttachments.CopyToAsync(new FileStream(savedFileName, FileMode.Create)); FileInfo infoFile = new FileInfo(savedFileName); string extension = infoFile.Extension.Replace(".", ""); var caseOfficer = _context.Users.Where(w => w.Id == tennantId.ToString()).FirstOrDefault(); if (Constants.imageExtensions.Contains(extension)) { fileAttachmentType = FileAttachments.FileAttachmentTypes.Image; } else if (extension.Contains("pdf")) { fileAttachmentType = FileAttachments.FileAttachmentTypes.PDF; } else if (Constants.videoFormats.Contains(extension)) { fileAttachmentType = FileAttachments.FileAttachmentTypes.Video; } else if (Constants.excelExtensions.Contains(extension)) { fileAttachmentType = FileAttachments.FileAttachmentTypes.Excel; } else if (Constants.wordExtensions.Contains(extension)) { fileAttachmentType = FileAttachments.FileAttachmentTypes.Word; } else if (Constants.audioExtensions.Contains(extension)) { fileAttachmentType = FileAttachments.FileAttachmentTypes.Voice; } var test = fileAttachmentType; FileAttachments attachments = new FileAttachments { DocumentPath = filePath, CaseId = resultCaseId, FullPath = savedFileName, FileSize = infoFile.Length, OrignalFileName = fileAttachments.FileName, FileAttachmentType = fileAttachmentType, TennantId = await GetCurrentTennantId(), Extension = infoFile.Extension.Replace(".", "").ToLower(), UploadedBy = caseOfficer.Id, CreatedDate = DateTime.Now, File = uniqueFilename, ContentType = fileAttachments.ContentType, isActive = true, isDeleted = false }; _context.Add(attachments); await _context.SaveChangesAsync(); MISAuditTrail _auditrail = new MISAuditTrail(); _auditrail.MISObjectId = resultCaseId; _auditrail.TennantId = tennantId; _auditrail.CreatedBy = caseOfficer.FirstName; _auditrail.IPAddressBytes = this.HttpContext.Connection.RemoteIpAddress.ToString(); _auditrail.AuditType = (int)fileAttachmentType; _auditrail.Action = "File was Uploaded " + attachments.FileAttachmentType.GetDisplayName() + "Filename: "+ attachments.OrignalFileName.ToString(); _auditrail.CreatedDate = DateTime.Now; _auditrail.isActive = true; _auditrail.isDeleted = false; _context.Add(_auditrail); await _context.SaveChangesAsync(); } } _toast.AddInfoToastMessage("Files has been upload sucesfully"); return RedirectToAction("Edit", "MISObjects", new { id = resultCaseId }); } }

I would like to acheive something like this.

在此处输入图像描述

This medium article by Dmirty Sikorsky seems to be this what you are looking for. The source code with the demo project is available on GitHub repo .

[HttpPost]
public async Task<IActionResult> Index(IList<IFormFile> files)
{
  Startup.Progress = 0;

  long totalBytes = files.Sum(f => f.Length);

  foreach (IFormFile source in files)
  {
    string filename = ContentDispositionHeaderValue.Parse(source.ContentDisposition).FileName.Trim('"');

    filename = this.EnsureCorrectFilename(filename);

    byte[] buffer = new byte[16 * 1024];

    using (FileStream output = System.IO.File.Create(this.GetPathAndFilename(filename)))
    {
      using (Stream input = source.OpenReadStream())
      {
        long totalReadBytes = 0;
        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(10); // It is only to make the process slower
        }
      }
    }
  }

  return this.Content("success");
}

[HttpPost]
public ActionResult Progress()
{
  return this.Content(Startup.Progress.ToString());
}

From the article:

In general, we just need to count the bytes number read from a request input stream, compare it with the total request stream length and then get this value from the client-side

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM