I have a MVC4 application with
A View who use bootstrap progress bar ( It's a partial view ) and Kendo UI for upload a file like this :
@using MyApplication.Web.Resources.Views.Contact; <div class="row"> <div class="span6"> <form class="form-horizontal well" method="post" action="@Url.Action("ImportContact","ContactAsync")"> @Html.ValidationSummary(true) <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> <fieldset> <legend>Contact</legend> <p> Some text... </p> @(Html.Kendo().Upload() .Name("files")) <div class="progress progress-striped"> <div class="bar" style="width: 0%;"></div> </div> <div class="form-actions"> <button type="submit" class="btn btn-primary" onclick="importMessage()">@Contact.ValidationButton</button> <button type="submit" class="btn btn-secondary" onclick="window.location.href='@Url.Action("Index")';return false;">@Contact.CancelButton</button> </div> </fieldset> </form> </div> </div>
And a Async Controller like this :
public class ContactAsyncController : AsyncController { private BackgroundWorker worker = new BackgroundWorker(); public ContactAsyncController(IContactService cs) { _contactService = cs; } // // POST: /Contact/ImportContactAsync [HttpPost] public void ImportContactAsync(IEnumerable<HttpPostedFileBase> files) { AsyncManager.OutstandingOperations.Increment(); worker.WorkerReportsProgress = true; worker.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); worker.DoWork += (o, e) => ImportContact(files, e); worker.RunWorkerCompleted += (o, e) => { AsyncManager.OutstandingOperations.Decrement(); }; worker.RunWorkerAsync(); } private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) { Debug.WriteLine(e.ProgressPercentage.ToString() + "%"); } private void ImportContact(IEnumerable<HttpPostedFileBase> files, DoWorkEventArgs e) { try { if (files != null) { string path = ""; string extension = ""; foreach (HttpPostedFileBase file in files) { if (file != null) { // New changes - first save the file on the server file.SaveAs(Path.Combine(Server.MapPath("~/Temp/Import"), file.FileName)); // Now create a path to the file path = Path.Combine(Server.MapPath("~/Temp/Import"), file.FileName); extension = Path.GetExtension(file.FileName); } else { // ... } } if (extension == ".pst") // PST { ImportContactPst(path); } else { // ... } } } catch { ViewBag.Error = myApplication.Web.Resources.Views.Contact.Contact.ErrorMessage; } } private void ImportContactPst(string path) { // Some code ... Session["test"] = // My percentage } public ActionResult ImportContactCompleted() { return RedirectToAction("Index","Contact"); } }
And I want to make progress my progress bar. So for this, I thought to do a script in my view like this :
<script>
$(document).ready(function () {
var progresspump = setInterval(function () {
/* query the completion percentage from the server */
$.ajax({
type: "GET",
url: "@Url.Action("GetProgressBar")",
dataType: "json",
cache: false,
success: function (data) {
var percentComplete = parseInt(data.PercentComplete);
if (percentComplete == null || percentComplete == 100) {
$(".progress").removeClass("active"); // we're done!
$(".progress .bar").css("width", "100%");
} else { // update the progress bar
$(".progress").addClass("active");
$(".progress .bar").css("width", percentComplete + "%");
}
},
error: function (xhr, textStatus, thrownError) {
console.log(xhr.statusText);
console.log(xhr.responseText);
console.log(xhr.status);
console.log(thrownError);
}
});
}, 3000);
});
</script>
Where GetProgressBar give me the perrcentage that I want, but it doesn't work because this method wait that the asynchronous method ( ImportContact ) finishes to do his job ... There are an update of the progress bar only at the end of the upload method.
public ActionResult GetProgressBar()
{
try
{
if (this.Session["test"] != null)
{
return Json(new { PercentComplete = this.Session["test"] }, JsonRequestBehavior.AllowGet);
}
else
return Json(0, JsonRequestBehavior.AllowGet);
}
catch
{
ViewBag.Error = myApplication.Web.Resources.Views.Contact.Contact.ErrorMessage;
return View();
}
}
So, as you can see ( at the beginning ), I have implemented the progressChanged event but I don't know how to use it to update my progress bar in my View... Can you help me ?
Thank you all for reading and trying to understand this, if you want more informations please tell me.