Progress Bar com ASP.NET MVC e AJAX

Hoje vou compartilhar para vocês uma maneira simples de se fazer um Progress Bar (barra de progresso) em ASP.NET MVC utilizando jQuery e Ajax. Essa é uma ótima dica para se levar em conta a experiência do usuário com sua aplicação, em situações em que ocorrem uma requisição ao Controller que demande um tempo, ocasionando uma confusão por parte do usuário em saber o que está acontecendo, se ocorreu o resultado esperado, etc.

progressbar

A lógica a ser utilizada é bem simples. Basicamente, teremos um objeto estático no Controller, responsável por armazenar a informação do processo em execução, como por exemplo Etapa atual e Descrição,e um Timer no front acessando o valor desse objeto estático e exibindo para o usuário.

Para a demonstração do código a seguir, foi utilizado as seguintes tecnologias:

  • ASP.NET MVC 5
  • jQuery 1.11.2
  • jQuery.UI 1.11.4

 

Imaginemos que temos um método no nosso Controller com nome FazendoAlgo.


public JsonResult FazendoAlgo()
{

for (int i = 1; i < 100; i++)
{
System.Threading.Thread.Sleep(1000);
}

return Json("Feito algo com sucesso", JsonRequestBehavior.AllowGet);

}

Em nossa View, temos um botão que chama o método FazendoAlgo atravéz uma requisição Ajax, e exiba a mensagem de retorno apenas ao termino do procedimento.


$.ajax({
            url: "/Controller/FazendoAlgo",
            type: "GET",
            dataType: "JSON",
            success: function (retorno) {
                alert(retorno);
            }
        });

Neste caso, o método FazendoAlgo somente retornará após 10 segundos. O usuário terá um delay de 10 segundos entre uma solicitação e a resposta, o que dependendo do caso pode ser crucial para seu negócio, fazendo com que ele feche a janela e vá embora. Claro que não se pode generalizar, mas se pensando em experiência do usuário, você deve mantê-lo informado do que está acontecendo.

Para isso, iremos usar o Progressbar do jQuery e faremos algumas pequenas alterações em nosso Controller para comunicar o progressbar do andamento da solicitação. Crie uma nova div com o id progressbar no local da sua pagina onde deseja exibir.


public class Progresso { public int Etapa { get; set; } public string Descricao { get; set; } }

Agora defina um novo Progresso privado e estatico dentro do seu Controller


private static Progresso Progresso = new Model.Progresso();

 

A lógica do procedimento é simples. O que faremos alterar os valores do Progresso dentro de cada nó em nosso método FazendoAlgo, ficando da seguinte maneira.

 


public JsonResult FazendoAlgo()
        {
            for (int i = 1; i < 100; i++)
            {
                Progresso.Etapa = i;
                Progresso.Descricao = "Realizando etapa n° " + i;
                System.Threading.Thread.Sleep(1000);
            }
            Progresso.Etapa = 100;
            Progresso.Descricao = "Concluido";
            return Json("Feito algo com sucesso", JsonRequestBehavior.AllowGet);
        }

Basta agora acessarmos essa informação do Progresso pela view  e exibir para o usuário. Para isso, criaremos um novo Interval que terá a responsabilidade de acessar um novo método no Controller, pegar o valor do Progresso e exibir para o usuário com o Progressbar.

Crie um novo método GetProgress no Controller com a seguinte instrução


public JsonResult GetProgress()
        {
            return Json(Progresso, JsonRequestBehavior.AllowGet);
        }

Agora crie uma nova função JavaScript na sua view para acessar o valor do Progresso

 


function GetProgress(timer) {
            $.ajax({
                type: 'GET',
                url: '/Controller/GetProgress',
                datatype: 'json',
                success: function (progresso) {
                    if (progresso.Etapa != 100) {
                        $("#progressbar").html(progresso.Descricao);
                        $("#progressbar").progressbar({
                            value: (progresso.Etapa)
                        });
                    }
                    else {   
                        clearInterval(timer);
                    }
                }
            });
        }

Agora temos que alterar a chamada Ajax do método FazendoAlgo para acionar o nosso Interval que por fim irá nos trazer o resultado do progresso, ficando da seguinte maneira

 


$.ajax({
            url: "/Home/FazendoAlgo",
            type: "GET",
            dataType: "JSON",
            success: function (retorno) {
                timer = setInterval(function () {
                    GetProgress(timer);
                }, 2000);
            }
        });

Pronto!

Se você realizou todas essas etapas, seu Progressbar estará funcionando e exibindo etapa por etapa do que esta sendo feito no Controller.  O Interval  está definido para atualizar o Progressbar a cada 2 segundos. Quando o progresso atingir o valor de 100, o Interval será parado.

Espero que esse artigo tenha sido útil, até a próxima.

  • Rafael Gil Silva

    Gostei da ideia, mas o fato do sistema chamar o interval no success do “FazendoAlgo”, não faria a chamada do GetProgress ser chamado apenas quando houver a resporta do FazendoAlgo, derrubando o proposito do progressbar?