3

I'm writing a file upload in ASP.Net Core and I'm trying to update a progress bar but when the Progress action is called from javascript, the session value isn't updated properly.

The progress is saved in the user Session using:

public static void StoreInt(ISession session, string key, int value)
{
    session.SetInt32(key, value);
}

The upload:

$.ajax(
  {
      url: "/Upload",
      data: formData,
      processData: false,
      contentType: false,
      type: "POST",
      success: function (data) {
          clearInterval(intervalId);
          $("#progress").hide();
          $("#upload-status").show();
      }
  }
);

Getting the progress value:

intervalId = setInterval(
  function () {
      $.post(
        "/Upload/Progress",
        function (progress) {
            $(".progress-bar").css("width", progress + "%").attr("aria-valuenow", progress);
            $(".progress-bar").html(progress + "%");
        }
      );
  },
  1000
);

Upload Action:

[HttpPost]
public async Task<IActionResult> Index(IList<IFormFile> files)
{
    SetProgress(HttpContext.Session, 0);
    [...]

    foreach (IFormFile file in files)
    {
        [...]
        int progress = (int)((float)totalReadBytes / (float)totalBytes * 100.0);
        SetProgress(HttpContext.Session, progress);
        // GetProgress(HttpContext.Session) returns the correct value
    }

    return Content("success");
}

Progress Action:

[HttpPost]
public ActionResult Progress()
{
    int progress = GetProgress(HttpContext.Session);
    // GetProgress doesn't return the correct value: 0 when uploading the first file, a random value (0-100) when uploading any other file

    return Content(progress.ToString());
}
5
  • Do you test this in local and what is the length of file you upload? Commented Feb 10, 2017 at 17:10
  • I tried in local and on a remote server, both failed. I also tried with single/multiple small/big file(s). Here I created a solution to reproduce the issue: github.com/Fxbouffant/FileUploadCore The progress action always returns 0 while the file is still being uploaded. Then it returns 100 when the file is uploaded, no value between. Commented Feb 13, 2017 at 15:13
  • 1
    The interval for check the progress is 1 second. Isn't it possible download ended before it check for the process? Commented Feb 13, 2017 at 15:17
  • 3
    It is not a good approach for upload progress. and it will not be smooth progressing. I do this by xmlHttpRequest that creates a live connection, But it is asp.net not mvc. Do you want that? Commented Feb 13, 2017 at 15:20
  • Thank you, that's perfect. I used the xhr event to update the progression. Commented Feb 13, 2017 at 16:04

1 Answer 1

15

Alright, I used the solution suggested by @FarzinKanzi which is processing the progress client side instead of server side using XMLHttpRequest:

$.ajax(
  {
      url: "/Upload",
      data: formData,
      processData: false,
      contentType: false,
      type: "POST",
      xhr: function () {
          var xhr = new window.XMLHttpRequest();
          xhr.upload.addEventListener("progress", function (evt) {
              if (evt.lengthComputable) {
                  var progress = Math.round((evt.loaded / evt.total) * 100);
                  $(".progress-bar").css("width", progress + "%").attr("aria-valuenow", progress);
                  $(".progress-bar").html(progress + "%");
              }
          }, false);
          return xhr;
      },
      success: function (data) {
          $("#progress").hide();
          $("#upload-status").show();
      }
  }
);

Thank you for your help.

Sign up to request clarification or add additional context in comments.

2 Comments

Sorry I don't have enough rep to upvote your comments :/
Do not worry brother.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.