1

I am using ASP.NET MVC 4 application, I need to Display messages in the Client, by sending messages from Controller to Client.

My requirement is user click a button in UI and i will process the files on the server and Display message in UI on end of each foreach file i process. i need to show the File names in the Client Using ASP.NET MVC.

Can any one Help how to show the messages in the Client by calling client method from server on for-each loop each time.

I am able to call the controller and end of each controller I am sending final message to UI, but how to send on each foreach loop iteration?

R Kumar
  • 157
  • 1
  • 2
  • 12

2 Answers2

1

Try this: Script method to update progress based on predefined interval you want

Controller:

public class HomeController : Controller
{
    private static IDictionary<Guid, int> tasks = new Dictionary<Guid, int>();

    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Start()
    {
        var taskId = Guid.NewGuid();
        tasks.Add(taskId, 0);

        Task.Factory.StartNew(() =>
        {
            for (var i = 0; i <= 100; i++)
            {
                tasks[taskId] = i; // update task progress
                Thread.Sleep(50); // simulate long running operation
            }
            tasks.Remove(taskId);
        });

        return Json(taskId);
    }

    public ActionResult Progress(Guid id)
    {
        return Json(tasks.Keys.Contains(id) ? tasks[id] : 100);
    }
}

View:

<script type="text/javascript">

function updateMonitor(taskId, status) {
    $("#" + taskId).html("Task [" + taskId + "]: " + status);
}

$(function () {

    $("#start").click(function (e) {
        e.preventDefault();

        $.post("Home/Start", {}, function (taskId) {

            // Init monitors
            $("#monitors").append($("<p id='" + taskId + "'/>"));
            updateMonitor(taskId, "Started");

            // Periodically update monitors
            var intervalId = setInterval(function () {

                $.post("Home/Progress", { id: taskId }, function (progress) {
                    if (progress >= 100) {
                        updateMonitor(taskId, "Completed");
                        clearInterval(intervalId);
                    } else {
                        updateMonitor(taskId, progress + "%");
                    }
                });

            }, 100);

        });
    });

});

Start new task …

0

You have to write an ActionResult that progressively write result to the response. so you can show the user some data in every foreach loop iteration. I have written a simple ActionResult that writes a number every 2 seconds:

public class ProgressiveResult : ActionResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        for (int i = 0; i < 20; i++)
        {
            context.HttpContext.Response.Write(i.ToString());
            Thread.Sleep(2000);
            context.HttpContext.Response.Flush();
        }
        context.HttpContext.Response.End();
    }
}

and this is an action that returns this result:

public ActionResult LongProcess()
{
   return new ProgressiveResult();
}

So you can write an ActionResult and write your foreach code in ExecuteResult method.

UPDATE:

You can make this call with an Ajax request and return result with a simple code like the following code:

var result = "";
function showResult() {
    if (result !== oReq.responseText) {
        result = oReq.responseText;
        console.log(result);
    }
}
var oReq = new XMLHttpRequest();
oReq.open("get", "/Home/LongProcess", true);
oReq.send();
setInterval(showResult, 1000);
alisabzevari
  • 8,008
  • 6
  • 43
  • 67
  • Thnaks But how to display the response message in UI – R Kumar Jun 14 '15 at 16:20
  • Hey Having an issue i am calling the controller when user click on submit button.@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "formUpload", enctype = "multipart/form-data", onsubmit = "progressStatus();" })) {
    Upload File
    @ViewBag.Message

    }
    – R Kumar Jun 15 '15 at 05:06
  • if i call the function progressStatus() { debugger; var oReq = new XMLHttpRequest(); oReq.open("get", "/Home/ProcessMessage", true); oReq.send(); setInterval(showResult, 1000); function showResult() { if (result !== oReq.responseText) { result = oReq.responseText; $("#progressbar").html(result); } } } on
    i am getting HTTP Error
    – R Kumar Jun 15 '15 at 05:16
  • Please do not share code through SO. The flow of conversation must be permanent in the website and permanently sharing this volume of code through google drive is not a good idea. It is better to talk specifically about error. Please give more detailed information about your exception or http error you get. – alisabzevari Jun 15 '15 at 05:57
  • My issues is i Am calling the java Script Method on
    , So If i Call this method i am getting error on the c# context.HttpContext.Response.Flush(); How to call submit method and Javascript Method because button is submit it's calling index of my controller . in the progressStatus method i have the code you have given..input is under @using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "formUpload", enctype = "multipart/form-data" }))
    – R Kumar Jun 15 '15 at 06:04
  • I am wonderting because i call index action and the Action is returning the View Back so the HTTP context is giving error in that case how to fix this – R Kumar Jun 15 '15 at 06:08
  • What is the exception message that you get in c#? – alisabzevari Jun 15 '15 at 06:11
  • An exception of type 'System.Web.HttpException' occurred in System.Web.dll but was not handled in user code Additional information: The remote host closed the connection. The error code is 0x80070057. – R Kumar Jun 15 '15 at 06:20
  • When you write javascript code for onclick event of submit button, browser runs your javascript code and submit you form. So submitting the form cancels your request sent by javascript. You can prevent this behavior by returning false in you progressStatus function. see http://stackoverflow.com/questions/12944329/add-onclick-function-to-a-submit-button for more details. – alisabzevari Jun 15 '15 at 06:27
  • I tried But Still the same error function progressStatus() { var oReq = new XMLHttpRequest(); oReq.open("get", "/Home/ProcessMessage", true); oReq.send(); setInterval(showResult, 1000); function showResult() { var result = ""; if (result !== oReq.responseText) { result = oReq.responseText; debugger; $("#progressbar").html(result); } } return false; } – R Kumar Jun 15 '15 at 06:34
  • Check this --> http://stackoverflow.com/questions/30838639/asp-net-mvc-4-call-back-from-server-to-client/30838726 – R Kumar Jun 15 '15 at 06:47
  • I think it is better to ask your second question. That is the problem of getting error when click on the submit button. My answer is the easiest way to solve this problem. If you don't want to solve your problem this way you have to work with web sockets and SignalR (in ASP.NET) that is more complicated. So I recommend you to ask you question about getting error – alisabzevari Jun 15 '15 at 06:52
  • This way i have to do a get call but when i doing that i was getting error in the context.HttpContext.Response.Flush(); Can you please hlep me this way how to return the message to Client – R Kumar Jun 15 '15 at 06:55
  • The way I have described will solve your problem. The problem is that submitting your page will cancel your ajax request so you will get the error. As I said this is another question. Try to describe this second problem in a new question. I know that people will help you immediately :) – alisabzevari Jun 15 '15 at 07:00
  • http://stackoverflow.com/questions/30840831/asp-net-mvc-4-ajax-request-cancels-on-submit – R Kumar Jun 15 '15 at 08:47