1

I am having problem with getting the progress bar working properly I have setup for when a file is uploaded. The progress bar works fine but however the bar doesn't work in sync with the size of the file. So if the file is 80 MB and if the file is still being processed in the back end the progress bar will always says upload 100%.

I am not sure where am going wrong in the code? Basically want the progress bar to be in sync with code being processed in the back end.

Here is progress so far

Controller:

//
// POST

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UploadMultipleFiles(IEnumerable<HttpPostedFileBase> files)
    {
        int count = 0;

        if (files != null)
        {
            foreach (var file in files)
            {
                if (file != null && file.ContentLength > 0)
                {
                    FileUploadService service = new FileUploadService();
                    var postedFile = Request.Files[0];

                    StreamReader sr = new StreamReader(postedFile.InputStream);
                    StringBuilder sb = new StringBuilder();
                    DataTable dt = CreateTable();
                    DataRow dr;
                    string s;
                    int j = 0;

                    while (!sr.EndOfStream)
                    {
                        while ((s = sr.ReadLine()) != null)
                        {
                            //Ignore first row as it consists of headers
                            if (j > 0)
                            {
                                string[] str = s.Split(',');

                                dr = dt.NewRow();
                                dr["Postcode"] = str[0].ToString();
                                dr["Latitude"] = str[2].ToString();
                                dr["Longitude"] = str[3].ToString();
                                dr["County"] = str[7].ToString();
                                dr["District"] = str[8].ToString();
                                dr["Ward"] = str[9].ToString();
                                dr["CountryRegion"] = str[12].ToString();
                                dt.Rows.Add(dr);
                            }
                            j++;
                        }
                    }
                    // Save to database
                    service.SaveFilesDetails(dt);
                    sr.Close();
                    count++;
                }
            }
        }
        return new JsonResult { Data = "Successfully " + count + " file(s) uploaded" };
    }

View:

@{
 ViewBag.Title = "File Upload";
 Layout = "~/Views/Shared/_LayoutPage.cshtml";
}

<h2>Upload a CSV File</h2>

@using (Ajax.BeginForm("UploadMultipleFiles", "File", new AjaxOptions() {      HttpMethod = "POST" }, new { enctype = "multipart/form-data" }))
{
  @Html.AntiForgeryToken()
<div class="row">
    <div class="col-md-5">
        <input type="file" name="files" id="fu1" />
    </div>
    <div class="col-md-2">
        <input type="submit" class="btn btn-default" value="Upload File" />
    </div>
</div>
}

<div class="progress">
   <div class="progress-bar">0%</div>
</div>
<div id="status"></div>
<div id="loading" class="loader">Loading...</div>
<style>
.progress {
    position: relative;
    width: 400px;
    border: 1px solid #ddd;
    padding: 1px;
}

.progress-bar {
    width: 0px;
    height: 20px;
    background-color: #57be65;
}
 </style>
 @section scripts{
 <script src="http://malsup.github.com/jquery.form.js"></script>
 <script>
    $(document).ready(function () {
        (function () {
            var bar = $('.progress-bar');
            var percent = $('.progress-bar');
            var status = $('#status');
            $('#loading').hide();
            $('form').ajaxForm({
                beforeSend: function () {
                    status.empty();
                    var percentValue = '0%';
                    bar.width(percentValue);
                    percent.html(percentValue);
                },
                uploadProgress: function (event, position, total, percentComplete) {
                    var percentValue = percentComplete + '%';
                    bar.width(percentValue);
                    percent.html(percentValue);
                    $('#loading').show();
                },
                success: function (d) {
                    var percentValue = '100%';
                    bar.width(percentValue);
                    percent.html(percentValue);
                    $('#fu1').val('');
                    $('#loading').hide();
                  //alert(d);
                },
                complete: function (xhr) {
                    status.html(xhr.responseText);
                }
            });
        })();
    });

</script>
}

1 Answer 1

3

Your code is working fine. You have upload progress, so you only get percent of data passed to server. After that your client have no idea how long server processes your data and how much of it has been processed. In fact the only long time running operation you have after file is uploaded is saving it to the database. As I know there is no way you can know how much time the query left to complete, so you can't get progress. So the only thing I can suggest here is to switch to some inifinite loading icon with "processing" label after file upload is 100% complete.

In case you had more than one long time running operations you could pass progress after each operation via SignalR for example. But you won't be able to get progress of each operation (of course depends on operation) only percent of operations completed.

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

7 Comments

Thanks Dmitri for your suggestion and it makes alot of sense. However can you perhaps give me an example of the processing label suggestion you mentioned above? Does it get placed where I am processing the data and saving it to the database?
Glad if could help. You should do this on client. On uploadProgress event, when you get percentComplete = 100, means that your data is uploaded and server is processing it. So at this time you can hide your progress bar and show some infinite loading gif image (or you can implement loading animation with css) and add some span with info message like 'processing'. Then on 'success' (or 'complete') event you can hide 'processing' elements as you know your data is processed by server.
Hi Dmitri that makes sense, however how do I know on the client side that when the server side process has started and completed?
Server side process starts as soon as data is uploaded - when uploadProgress event handler get percentComplete = 100. And it is completed as soon as you receive success or complete events.
Thanks Dmitri. Ok I added CSS rotating animation as suggested by you. However I am not sure if It is working properly as the rotating animation quickly disappears after the file has been uploaded. I have modified my code to show the changes. Can you please advice?
|

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.