I just want to create a progress bar while long running server calls. I could not create a ajax post request to the controller while the controller is doing a long running job.
I want to create an additional action to get the actual statement of current long running task. I tried to create poll in ajax request then i can able to return the status from the server side and display it in a client side progress bar. Any ideas ?
To display the progress bar, we have to write the below code on the same view page where we want our progress bar and script on the same page as well. The below JavaScript function is used to update the progress bar to display the loading of data in percentage: function updateProgress(count, max, html) { $("#h3").
First we have to create an Asp Mvc project in visual studio. To do that, Open Visual Studio -> New Project -> A new dialog window will appear -> In left pane select C# ->select Web -> Select "ASP.NET MVC 4 Application" name your project and click ok.
The right and easiest way to do this is with SignalR. Please download Microsoft SignalR in https://www.nuget.org/packages/Microsoft.AspNet.SignalR/2.1.2
Create a hub class in separate folder in project path called hubs, add two class files into the hubs folder
Startup.cs
using Owin; using Microsoft.Owin; [assembly: OwinStartup(typeof(SignalRChat.Startup))] namespace SignalRChat { public class Startup { public void Configuration(IAppBuilder app) { // Any connection or hub wire up and configuration should go here app.MapSignalR(); } } }
ProgressHub.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Web; using Microsoft.AspNet.SignalR; namespace RealTimeProgressBar { public class ProgressHub : Hub { public string msg = "Initializing and Preparing..."; public int count = 1; public static void SendMessage(string msg , int count) { var message = "Process completed for " + msg; var hubContext = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>(); hubContext.Clients.All.sendMessage(string.Format(message), count); } public void GetCountAndMessage() { Clients.Caller.sendMessage(string.Format(msg), count); } } }
In controller,
// assemblies using Microsoft.AspNet.SignalR; using RealTimeProgressBar; //call this method inside your working action ProgressHub.SendMessage("initializing and preparing", 2);
In View,
<!--The jQuery library is required and is referenced by default in _Layout.cshtml. --> <!--Reference the SignalR library. --> <script src="~/Scripts/jquery.signalR-2.1.2.min.js"></script> <!--Reference the autogenerated SignalR hub script. --> <script src="~/signalr/hubs"></script> <!--SignalR script to update the chat page and send messages.--> <script type="text/javascript"> $(document).ready(function () { $("#progressBar").kendoProgressBar({ min: 0, max: 100, type: "percent", }); }); function StartInvoicing() { var progressNotifier = $.connection.progressHub; // client-side sendMessage function that will be called from the server-side progressNotifier.client.sendMessage = function (message, count) { // update progress UpdateProgress(message, count); //alert(message); }; // establish the connection to the server and start server-side operation $.connection.hub.start().done(function () { // call the method CallLongOperation defined in the Hub progressNotifier.server.getCountAndMessage(); }); } // Update the progress bar function UpdateProgress(message, count) { var result = $("#result"); result.html(message); $("#progressBar").data("kendoProgressBar").value(count); } </script>
For more details refer some existing articles with the help of google
I had a long running service for that, I have given a basic idea below. Use it as per your requirements.
ProgressArgs
getProgress()
which will return a JSON string progress by ajax.getProgress()
function which once started will call the server at regular intervals for progress till the process is completed.I have given a rough example to implement it. Hope it may help you.
The class for progress arguments structure
public class ProgressArgs { public int Completed { get; set; } public int Total { get; set; } public int Percentage { get; set; } public string Status { get; set; } }
In the Process I kept on updating the stats in the database
public void LongRunningProcess() { ProgressArgs result = new ProgressArgs(); result.Completed = 0; result.Total = userList.Count; foreach (var item in itemList) { //Do Some processing which u want to do result.Total++; result.Percentage = (result.Completed * 100) / result.Total; result.Status = "Processing"; string strToSave = Newtonsoft.Json.JsonConvert.SerializeObject(result); //update the strToSave to the database somewhere. } //after completing of processing result.Total++; result.Percentage = (result.Completed * 100) / result.Total; result.Status = "Completed"; string strToSave = Newtonsoft.Json.JsonConvert.SerializeObject(result); //update the strToSave to the database somewhere. }
The C# Action to get the progress by ajax
public string getProgress() { string strJSON = config.GetValue("progress"); //Get stats from the database which is saved in json return strJSON; }
The Javascript Code
//Ajax Get Progress function function getProgress() { var dataToSend = ''; $.ajax({ url: '@Url.Action("getProgress")', //Link to the action method type: 'POST', contentType: 'application/json; charset=utf-8', data: dataToSend, success: function (response) { console.log(response); if (response != null) { data = JSON.parse(response); console.log(data); //update the progressbar progressbar.progressbar("value", data.Percentage); //When the jobalert status is completed clear the interval if (data.Status == 0) { setTimeout(getProgress, 800); //TImout function to call the respective function at that time } serviceCompleted(data); function to call after completing service } }, error: function (xhr) { alert('Error: There was some error while posting question. Please try again later.'); } }); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With