Pergunta

Eu tenho um botão no meu webform. Ao clicar neste botão irá fazer um HttpWebRequest durante o manipulador de eventos onclick. Após o pedido, copiar a resposta do pedido em HttpContext.Current.Response e enviar para o cliente.

Esta solicitação da web pode demorar um pouco (até 5 segundos, uma vez que está gerando um relatório). Durante esse tempo, o usuário não tem indicação de que alguma coisa está acontecendo, exceto para a barra de progresso do navegador e o ícone IE fiação (se eles estão usando o IE). Então eu preciso de um indicador de carregamento enquanto isso está acontecendo.

Eu tentei usar javascript que os incêndios durante o evento onclick do botão (usando OnClientClick) e ao mesmo tempo que funciona, eu não sei como descobrir quando o pedido web está terminado. Desde que acabamos de enviar a resposta para o cliente, uma nova postagem completa não acontece.

Eu tentei envolvendo o botão em um UpdatePanel e usando o UpdateProgress, mas quando enviar a resposta para HttpContext.Current.Response e Response.End call (), obtemos um erro no javascript, desde o isn de resposta 't bem formados (estamos enviando de volta uma folha de excel para o usuário para download).

Uma vez que estamos enviando de volta um arquivo para usuários para download, eu não quero para pop-up uma janela separada, desde então, em IE que deseja obter a barra de informações bloqueando o download.

Todas as ideias aqui?

Foi útil?

Solução

Como uma alternativa para a biblioteca Professional AJAX.NET, jQuery tem um realmente nice maneira de fazer isso.

Dê uma olhada em neste exemplo de usar um .NET PageMethod (se possível em seu cenário).

Você define uma chamada de método página no jQuery, você pode rumo no seu loading ... mensagem em uma div oculta.

Diga o retorno de chamada que você deseja retornar em caso de sucesso (ou seja, quando o seu segundo relatório 5 é gerado) em seguida, esconder o carregamento e manipular os dados.

Dê uma olhada no javascript na minha página de contato para um exemplo (ver a fonte).

  1. Eu tenho um um botão na página, adicionar o jQuery onClick.
  2. Quando clicado que mostra um div carregamento escondido, faz uma chamada ajax para um método de página que leva os parâmetros do formulário.
  3. O método de página não-mail etc seguida, retorna para o formulário no método javascript onSuccess eu tenho lá.
  4. As peles onSuccess o carregamento div.

Outras dicas

Um truque simples eu usei no passado é para redirecionar para uma página intermediária com uma barra de progresso de animação (gif) e depois ter essa página fazer o pós real dos dados. (Ou mesmo pop-up uma camada com a animação nele e uma mensagem educada pedindo ao usuário para esperar um minuto ou dois)

O feedback simples do GIF animado cria a ilusão para o usuário final que o aplicativo não está parado e eles vão ser mais paciente.

Outra abordagem é entregar os dados fora de um segmento de trabalho e retornar imediatamente com uma mensagem informando que o relatório será enviado ou disponibilizado na seção "Relatórios" do site quando ele está pronto. Esta abordagem não tem o benefício de notificação instantânea quando o relatório for concluído embora.

Aqui está a minha solução:

  1. Faça o download e examinar as amostras de livre biblioteca Professional AJAX.NET .
  2. Escrever um AjaxMethod que cria o arquivo e retorna local do arquivo como um parâmetro.
  3. Escrever a função do lado do cliente para o método de chamada no Passo 2. Quando este método chamado de mostrar um indicador.
  4. Escrever um método de retorno de chamada do lado do cliente de ocultar a janela e mostrar / arquivo de download que o usuário solicitado.
  5. Adicionar uma função do lado do cliente chama yo seu elemento botão.

Quando o seu método no lado do servidor termina o retorno de chamada será chamado.

Espero que isso ajude!

A solução que eu estou apresentando aqui é destinado a mostrar um método para deixar um "Loading ..." caixa para aparecer enquanto você está processamento do lado do servidor e a desaparecer quando o processamento do lado do servidor está completa.

Eu vou fazer isso com a maquinaria AJAX muito básico (testado em FF, mas IE deve estar ok também), ou seja, não usando uma estrutura como protótipo ou jQuery ou Dojo, como você não especificou o seu conhecimento sobre eles.

Para que você entenda melhor o truque, o seguinte é apenas um pequeno exemplo e não pretende ser uma solução out-of-the-box. Eu não tendem a ser superficial, mas eu acho que um exemplo mais claro pode explicar melhor do que muitas palavras.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>First Example</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <style>
            .hidden {
                display: none;
            }
            .loadingInProgress {
                color: #FFFFFF;
                width: 75px;
                background-color: #FF0000;
            }
        </style>
    <script type="text/javascript">
        var httpRequest;
        if (window.XMLHttpRequest) { // Mozilla, Safari, ...
            httpRequest = new XMLHttpRequest();
            httpRequest.overrideMimeType('text/xml');
        } else if (window.ActiveXObject) { // IE
            try {
                httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
            }
            catch (e) {
                try {
                    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
                }
                catch (e) {}
            }
        }

        if (!httpRequest) {
            alert('Giving up :( Cannot create an XMLHTTP instance');
        }

        httpRequest.onreadystatechange = function(){
            switch (httpRequest.readyState) {
            case 1: // Loading
                document.getElementById('loading').className = "loadingInProgress";
                break;
            case 4: // Complete
                document.getElementById('loading').className = "hidden";
                if (httpRequest.status == 200) {
                    // perfect!
                } else {
                    // there was a problem with the request,
                    // for example the response may be a 404 (Not Found)
                    // or 500 (Internal Server Error) response codes
                }
                break;
            }
        };

        function go() {
            httpRequest.open('GET', document.getElementById('form1').action, true);
            httpRequest.send('');
        }
    </script>

  </head>
  <body>
      <div id="loading" class="hidden">Loading...</div>
      <form id="form1" name="form1" action="doSomething.php">
          <input type="button" value="Click to submit:" onclick="go()" />
      </form>
  </body>
</html>

Como você pode ver, há uma <div> que detém o "Carregando ..." mensagem.

O princípio é o de mostrar / ocultar o <div> dependendo XMLHttpRequest do objeto readyState.

Eu usei o manipulador onreadystatechange do XMLHttpRequest para desencadear a mudança readyState.

O back-end php uso roteiro I (declarado como action do formulário) faz exatamente um sono (5), para deixar o "Carregando ..." Mensagem aparecem durante 5 segundos.

<?php
sleep(5);
header('Cache-Control: no-cache');
echo "OK";
?>

O cabeçalho Cache-control: no-cache é necessário, já que geralmente se você não configurá-lo o navegador irá armazenar em cache a resposta evitando reenviar o pedido, se você deve precisar.

Uma boa fonte para a "introdução" documentação AJAX é Mozilla MDC .

A coisa toda poderia ser muito mais suavemente tratado por um quadro Javascript como Prototype, aproveitando-se da sua abordagem navegador seguro, economizando horas de depuração.


Editar:

Eu escolhi php 'porque eu não sei ASP.NET nem ASP, desculpe sobre isso.


Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top