Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I would probably submit the form using jQuery's ajaxForm().</p> <p>Then, onSuccess, call a function that begins further AJAX requests to poll the progress of the upload from your webserver, using JSON. Apart from having a URL to handle the file upload in ASP.NET, you would also need to have another means of returning the progress of some kind of asynchronous worker in JSON format.</p> <p>Once you get the JSON back, you can then feed this to a jQueryUI progress bar.</p> <p>For example, in an ASP .NET MVC application, I did something like this:</p> <p><strong>In the view Upload.aspx, begin the submission</strong></p> <pre><code>&lt;% using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data", id = "UploadForm" })) { %&gt; &lt;div&gt; &lt;input type="file" name="CSVFile" id="CSVFile" /&gt; &lt;button&gt;Upload&lt;/button&gt; &lt;/div&gt; &lt;% } %&gt; var pb = $('#prog'); var pbContainer = $('#pbcont'); var pbPercent = $('#progp'); var uploadForm = $('#UploadForm'); var status = $('#StatusDetail'); uploadForm.ajaxForm({ iframe: true, dataType: 'jason', success: function (data) { beginProcessing($.parseJSON($(data).text()), '" + Url.Action("UploadStatus", "Upload") + @"', pb, pbContainer, status, pbPercent); }, error: function (xhr, textStatus, error) { alert('Error: ' + textStatus); } }); </code></pre> <p><strong>Controller method to handle the initial upload</strong></p> <p>Here, I'm creating a unique ID for the upload when it begins, this is so I can identify the upload later on, when I want to find out it's progress.</p> <p>I'm using a worker class I wrote which handles the processing asynchronously - this is where you would want to asynchronously begin inserting your data into the database. </p> <p>By the time we reach this controller method, the FileStream should have reached the server, and so we can pass that to our worker to read the stream, parse the CSV and do the database work. Notice that here, I pass the StreamReader to my worker so it can handle all of that.</p> <pre><code> // NOTE: The parameter to this action MUST match the ID and Name parameters of the file input in the view; // if not, it won't bind. [HttpPost] public JsonResult Upload(HttpPostedFileBase CSVFile) { try { if (CSVFile == null || String.IsNullOrWhiteSpace(CSVFile.FileName)) return Json("You must provide the path to your CSV file", "text/plain"); if (!CSVFile.FileName.ToLower().Contains(".csv")) return Json("You can only upload CSV files", "text/plain"); Guid id = worker.BeginImport(dataReporistory, new StreamReader(CSVFile.InputStream)); //return some JSON var json = new { ID = id, name = CSVFile.FileName, size = CSVFile.ContentLength }; return Json(json, "text/plain"); } catch (Exception e) { return Json(Utilities.DisplayExceptionMessage(e), "text/plain"); } } </code></pre> <p><strong>Controller method to return progress update</strong></p> <pre><code> [HttpPost] public JsonResult UploadStatus(Guid id) { UploadJob job = Worker.GetJobStatus(id); return Json(job); } </code></pre> <p><strong>JavaScript in the view to handle the progress bar updating</strong></p> <p>As you will see above, the ajaxForm.Submit() method will call beginProcessing() from here during the onSuccess event, when the file has finished uploading.</p> <p>It will also pass the JSON it got from the Upload() controller method, which tells our view the ID of the upload to pass to the update URL when fetching the progress of the job from our worker.</p> <p>Once beginProcessing is called, it will do some work to setup a progress bar but basically then starts calling updateProgress() on a set timer interval. updateProgress is the function which does all the work of fetching the JSON from the webserver's UploadStatus page.</p> <p>Once updateProgress gets the JSON update from the webserver, it does some work to feed that into the jQuery UI progress bar that was inserted into a div on the page.</p> <pre><code>&lt;div id="pbcont"&gt; &lt;p style="display: inline-block;"&gt;&lt;strong&gt;Processing...&lt;/strong&gt;&lt;/p&gt; &lt;h3 style="display: inline-block;" id="progp"&gt;&lt;/h3&gt; &lt;div id="prog"&gt;&lt;/div&gt; &lt;br /&gt; &lt;div id="StatusDetail"&gt;&lt;/div&gt; &lt;/div&gt; function beginProcessing(response, url, pb, pbContainer, statusContainer, pbPercent) { if (!response.ID) { alert('Error: ' + response); return; } pb.progressbar({ value: 0 }); pbContainer .css('opacity', 0) .css('display', 'block'); //Set the interval to update process. var hasUpdated = false; var intervalID = setInterval(function () { updateProgress(url + '/' + response.ID, pb, statusContainer, pbPercent, intervalID); }, 500); } function updateProgress(url, pb, statusContainer, pbPercent, intervalID) { //Make an AJAX post to get the current progress from the server $.post(url, function (job) { var newValue = 0; var currentValue = pb.progressbar('value'); //The percentage value retrived from server: newValue = (job != null &amp;&amp; job.TotalItems != 0 ? (job.ProcessedItems / job.TotalItems * 100) : 0); if (newValue &gt; 0) hasUpdated = true; if (hasUpdated &amp;&amp; job == null) { newValue = 100; statusContainer.html("&lt;strong&gt;Status:&lt;/strong&gt; Finished"); clearInterval(intervalID); } if (!hasUpdated) currentValue = currentValue + 1; newValue = Math.max(currentValue, newValue); pb.progressbar("value", newValue); pbPercent.text(Math.round(newValue, 0) + '%'); if (job != null) statusContainer.html("&lt;strong&gt;Upload:&lt;/strong&gt; " + job.Status); }); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload