Atualizações de página dinâmica usando o XMLHTTP

Traduções deste artigo Traduções deste artigo
ID do artigo: 893659 - Exibir os produtos aos quais esse artigo se aplica.
Coluna de voz de suporte do ASP.NET

Atualizações de página dinâmica usando o XMLHTTP

Para personalizar esta coluna às suas necessidades, queremos convidá-lo para enviar suas idéias sobre tópicos que interessam a você e problemas que você deseja ver abordados em futuros artigos do Knowledge Base e colunas de voz de suporte. Você pode enviar suas idéias e comentários usando o Peça para ele formulário. Há também um link para o formulário na parte inferior desta coluna.
Expandir tudo | Recolher tudo

Neste artigo

INTRODUÇÃO

Uma das minhas maneiras favoritas de estudo de usabilidade do aplicativo da Web é observar a minha esposa a navegar por um site da Web. Ela pode fazer sua forma em torno da Internet muito bem, mas sabe pouco sobre o baixo nível aspectos técnicos (o que ela chama "coisas chatas") que fazer tudo funcionar.

Em uma noite recente, eu estava assistindo a minha esposa examinar um aplicativo de comércio eletrônico de um dos meninos grandes. Ela foi aprofundar em um produto listando usando várias listas suspensas, cada um de alimentação para fora da seleção feita anteriormente. Como ele clicou em um item em cada lista suspensa, a página é remetida para obter dados para o próximo drop-down. A experiência foi frustrante para ela, porque sua impressão foi de que estava levando muito tempo devido à parte traseira do post.

Ela estava com o nível de frustração poderia ter foi facilmente aliviado pelos desenvolvedores do aplicativo se XMLHTTP usados somente para recuperar os dados em vez de postar novamente. Isso é que se trata da coluna deste mês. Mostrarei como usar o XMLHTTP para atualizar uma parte de uma página da Web com dados de um serviço Web do Microsoft ASP.NET sem fazer uma postagem de volta. Isso vai ser realmente interessante! Confie em mim.

Visão geral

XMLHTTP funciona enviando uma solicitação para o servidor Web do cliente e retornando uma ilha de dados XML. Dependendo da estrutura do XML que é recebida, você pode usar XSLT ou o DOM XML para manipulá-lo e ligar partes da página com os dados. Esta é uma técnica extremamente poderosa.

Observação A Microsoft oferece um comportamento de serviço da Web para o Internet Explorer que faz chamadas assíncronas a serviços da Web do ASP.NET rápida e fácil. No entanto, esse comportamento não é suportado e não é a melhor maneira de atualizar uma página assíncrona. Em vez disso, você deve usar o XMLHTTP!

No exemplo que trabalharia através desta coluna, vou fazer três chamadas de serviço da Web a um serviço da Web do ASP.NET por meio de XMLHTTP. O serviço da Web irá consultar o banco de dados Northwind do SQL Server local e irá retornar um DataSet para o cliente na forma de um diffgram XML. Vou usar o DOM para analisar dados XML e atualizar dinamicamente partes da página. Tudo isso será feito sem uma postagem.

O serviço da Web

O serviço da Web que usarei é denominado DynaProducts. É um serviço da Web do ASP.NET básico que está escrito em C# e que contém três métodos a seguir.
  • GetCategories ? retorna um DataSet que contém todas as categorias na tabela Categorias.
  • GetProducts ? retorna um DataSet que contém todos os produtos da categoria são passados para o método.
  • GetProductDetails ? retorna um DataSet que contém detalhes sobre o produto cujo ProductID é passado para o método.

A página HTML

A primeira coisa que pode fazer sobre esse exemplo é que a página que Estou atualizando Embora o serviço da Web do ASP.NET não é uma página ASP.NET. É apenas uma página HTML normal. No entanto, adicionei uma quantidade razoável de JavaScript do lado do cliente para a página, e é esse script que faz com que as chamadas para o serviço da Web.

Vejamos o primeiro trecho de código da página HTML.
var objHttp;
var objXmlDoc;

function getDataFromWS(methodName, dataSetName, wsParamValue, wsParamName)
{

    // create the XML object
    objXmlDoc = new ActiveXObject("Msxml2.DOMDocument");

    if (objXmlDoc == null)
    {
        alert("Unable to create DOM document!");
        
    } else {

	    // create an XmlHttp instance
	    objHttp = new ActiveXObject("Microsoft.XMLHTTP");
	
	
	    // Create the SOAP Envelope
	    strEnvelope = "<soap:Envelope xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
	
	            " xsd=\"http://www.w3.org/2001/XMLSchema\"" +
	
	            " soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
	
	            "  <soap:Body>" +
	
	            "    <" + methodName + " xmlns=\"http://jimcoaddins.com/DynaProducts\">" +
	
	            "    </" + methodName + ">" +
	
	            "  </soap:Body>" +
	
	            "</soap:Envelope>";
	
	
	    // Set up the post
	    objHttp.onreadystatechange = function(){
	
	        // a readyState of 4 means we're ready to use the data returned by XMLHTTP
	        if (objHttp.readyState == 4)
	        {
	
	            // get the return envelope
	            var szResponse = objHttp.responseText;
							
	            // load the return into an XML data island
	            objXmlDoc.loadXML(szResponse);
	
	            if (objXmlDoc.parseError.errorCode != 0) {
	                var xmlErr = objXmlDoc.parseError;
	                alert("You have error " + xmlErr.reason);
	            } else {
	
	                switch(dataSetName)
	                {
	                    case "CategoriesDS":
	                        processCategory();
	                        break;
	
	                    case "ProductsDS":
	                        processProducts();
	                        break;
	
	                    case "ProductDetailDS":
	                        processProductDetails();
	                        break;
	
	                }
	            }
	
	        }
	     }
	
	    var szUrl;
	    szUrl = "http://dadatop/wsXmlHttp/DynaProducts.asmx/" + methodName;
	
	    if (wsParamValue != null)
	    {
	
	        szUrl += "?" + wsParamName + "=" + wsParamValue;
	    }
	
	    // send the POST to the Web service
	    objHttp.open("POST", szUrl, true);
	    objHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	    objHttp.send(strEnvelope);
	  }
}
Esta é a maior parte do código da página, e quero falar sobre ele em detalhes para que você compreenda o que está acontecendo.

Na parte superior deste bloco de script, criei duas variáveis: objHttp e objXmlDoc. Essas são as variáveis que usarei para meu objeto XMLHTTP e meu objeto DOM XML. Imediatamente após o que é a definição de função para a função getDataFromWS . Esta é a função que é responsável por fazer a chamada de cliente para o serviço da Web. Ele toma os quatro argumentos a seguintes, dois dos quais são opcionais:
  • methodName ? o nome do método para chamar o serviço Web.
  • dataSetName ? o nome do DataSet que é retornado pelo serviço da Web.
  • wsParamValue ? o valor do parâmetro que é passado para o serviço da Web, se aplicável. (Opcional)
  • wsParamName ? o nome do parâmetro que é passado para o serviço da Web, se aplicável. (Opcional)
Vamos dividir a função getDataFromWS em partes e discuta cada uma delas. Este é o primeiro trecho:
// create the XML object
    objXmlDoc = new ActiveXObject("Msxml2.DOMDocument");

    if (objXmlDoc == null)
    {
    		alert("Unable to create DOM document!");

    } else {

		// create an XMLHTTP instance
		objHttp = new ActiveXObject("Microsoft.XMLHTTP");
Este bloco de código cria o objeto XMLHTTP e o objeto de documento XML. Em seguida, posso começar a criar o envelope SOAP.
// Create the SOAP Envelope
strEnvelope = "<soap:Envelope xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
	
          " xsd=\"http://www.w3.org/2001/XMLSchema\"" +
	
          " soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
	
          "  <soap:Body>" +
	
          "    <" + methodName + " xmlns=\"http://jimcoaddins.com/DynaProducts\">" +
	
          "    </" + methodName + ">" +
	
          "  </soap:Body>" +
	
          "</soap:Envelope>";
Nesse código, estou atribuindo o envelope SOAP a uma variável de seqüência de caracteres para que eu possa passá-la para o serviço da Web. É realmente muito fácil de descobrir como formatar o envelope SOAP para o serviço Web. Simplesmente vá para o serviço da Web e, em seguida, clique em um dos métodos para ver um envelope SOAP para o método. Por exemplo, eis o que se vê ao navegar para o método GetCategories do wsXMLHTTP serviço da Web que criei para este artigo:

Recolher esta imagemExpandir esta imagem
Envelope.png


ASP.NET informa como o envelope SOAP deve ser formatado para um HTTP POST e um HTTP GET. No exemplo apresentado neste artigo, usarei HTTP POST.

Até aqui tudo bem. Agora vamos ver a próxima seção do código.
// Set up the post
objHttp.onreadystatechange = function(){
	
// a readyState of 4	means we're ready to use the	data returned by	XMLHTTP
	if (objHttp.readyState == 4)
	{
	
		// get	the return envelope
		   var	szResponse	= objHttp.responseText;
	
		   // load	the return into an XML data island
		   objXmlDoc.loadXML(szResponse);
	
		   if (objXmlDoc.parseError.errorCode != 0) {
			var xmlErr =	objXmlDoc.parseError;
				 alert("You have error " + xmlErr.reason);
	}
	else	
	{

		switch(dataSetName)
				{
					case "CategoriesDS":
						processCategory();
						break;
					case "ProductsDS":
						processProducts();
						break;
					case "ProductDetailDS":
					processProductDetails();
						break;

				}
			}
Quando uma solicitação é feita por meio de XMLHTTP, o objeto XMLHTTP usa uma propriedade readyState para acompanhar o status da solicitação. Quando todos os dados foi recebida novamente o serviço da Web, a propriedade readyState muda para um valor de 4. A propriedade onreadystatechange do objeto XMLHTTP permite configurar uma função de retorno de chamada que será chamada quando a propriedade readyState muda. Garantindo que os dados foram recebidos em sua totalidade, eu pode manter agindo em que os dados até que eu esteja pronto.

Depois que todos os dados foram recebidos, crio uma ilha de dados XML com a resposta usando a propriedade responseText . Como você provavelmente sabe, a resposta de um serviço Web está no formato XML. Nesse caso, estou retornando a um Microsoft ADO.NET DataSet.

A próxima seção deste bloco de código usa uma instrução switch para chamar a função apropriada com base no nome do DataSet que é retornado pelo serviço da Web. Entrarei em código para essas funções em detalhes mais adiante.

Agora vamos examinar o código que realmente executa a solicitação XMLHTTP.
var szUrl;
	szUrl = "http://dadatop/wsXmlHttp/DynaProducts.asmx/" + methodName;
	
	if (wsParamValue != null)
	{
	
	      	szUrl += "?" + wsParamName + "=" + wsParamValue;
	}
	
// send the POST to the Web service
	objHttp.open("POST", szUrl, true);
	objHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	objHttp.send(strEnvelope);
A variável szUrl contém o URL que é usado para chamar o serviço da Web para fins de clareza. Em seguida, tenho um se instrução move em todos os parâmetros são passados como um valor de seqüência de consulta . Em seu ambiente, você poderá adicionar os parâmetros para o envelope SOAP. De qualquer forma funcionará muito bem.

O método open do objeto XMLHTTP próxima é chamado. Eu usei os três primeiros argumentos do método open; o método, a URL e um valor booleano que especifica se será ou não a chamada assíncrona.
Importante Se você estiver fazendo uma chamada assíncrona como estou aqui, você deve configurar uma função de retorno de chamada através da propriedade onreadystatechanged .

Após o cabeçalho de solicitação para o tipo de conteúdo é definido, posso enviar a solicitação como um envelope SOAP usando a variável de seqüência de caracteres que preenchido anteriormente.

Agora passamos ao longo de todo o código que faz a solicitação XMLHTTP. Agora vamos dar uma olhada no código que lida com a interface no navegador e que lida com a resposta da chamada de serviço da Web.

Primeiro, examinaremos a função que é chamada quando a página for carregada pela primeira vez.
function getCategories()
{

  var func = "getDataFromWS('GetCategories', 'CategoriesDS')";
  document.all.lblCategoryDropdown.innerText = 
"Please wait while data is retrieved...";
  window.setTimeout(func, 1);

  }
A primeira coisa que faço nesta função é criar uma variável para armazenar a assinatura de função getDataFromWS. Faço isso porque eu vou chamar Window. setTimeout no final desta função para chamar a função getDataFromWS . O objetivo dessa abordagem é permitir que me exibir o status para o usuário enquanto aguarda a chamada de serviço Web ser concluída. Observe que eu estou mudando innerText de uma DIV para exibir uma mensagem indicando que os dados estão sendo recuperados. Em seguida, agendar a função getDataFromWS por meio da chamada setTimeout e defini-lo para ser executado em um milissegundo.

Processando a resposta do serviço da Web

Lembre-se anteriormente de que usei a propriedade onreadystatechanged para configurar uma função de retorno de chamada. Lembre-se também de que a função de retorno de chamada contém uma instrução switch que chama uma função específica com base no nome do DataSet. Nesse caso, o nome do DataSet é CategoriesDS. Portanto, a função processCategory será chamada a partir da função de retorno de chamada. Vamos dar uma olhada na função para ver como usar o DOM para analisar a resposta do serviço da Web.
function processCategory()
{

  // get an XML data island with the category data
  objNodeList = objXmlDoc.getElementsByTagName("Categories");
 
  // add default value to the drop-down
  document.forms[0].drpCategory.options[0] = new Option("Select a Category", 0);

  // walk through the nodeList and populate the drop-down
  for (var i = 0; i < objNodeList.length; i++) 
  {
      var dataNodeList;
      var textNode;
      var valueNode;

      dataNodeList = objNodeList[i].childNodes;
      valueNode = dataNodeList.item(0);
      textNode = dataNodeList.item(1);

      document.forms[0].drpCategory.options[i + 1] = 
new Option(textNode.text, valueNode.text);
      document.all.lblCategoryDropdown.innerText = "Select a Category:";
      document.forms[0].drpCategory.style.visibility = "visible";
       
    }

  }
Lembre-se de que a função getDataFromWS carregados XML da resposta para o objeto objXmlDoc . Na função processCategory , posso levar esse XML e analisar através dele para preencher a lista suspensa Categoria.

A primeira coisa que faço é criar um objeto IXMLDOMNodeList usando parte da resposta XML. O DataSet que retorno da chamada de serviço Web é retornado como um diffgram, e a única parte dessa resposta estou realmente interessado em dados da DataTable tiver inserido o DataSet. Posso obter para que, criando um objeto IXMLDOMNodeList do bloco XML que contém a tabela de dados.

Se você examinar o código para o serviço da Web, você verá que criar uma DataTable chamada categorias e adicioná-lo ao conjunto de dados. Quando o XML é retornado do serviço da Web, o conjunto de dados está contido dentro de um bloco de <CategoriesDS>e cada linha da DataTable está contida em blocos separados de <Categories>, conforme mostrado no arquivo XML abaixo.

</Categories></CategoriesDS>Os seguintes arquivos estão disponíveis para download da Microsoft Centro de download:
Recolher esta imagemExpandir esta imagem
Download
Baixe o pacote GetCategories.xml agora.
Recolher esta imagemExpandir esta imagem
Download
Baixe o pacote WSXMLHTTP.exe agora.Para obter mais informações sobre como baixar arquivos do Microsoft Support, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
119591 Como obter arquivos de suporte da Microsoft de serviços on-line
Microsoft examinou esse arquivo em busca de vírus. A Microsoft usou o software de detecção de vírus mais atual que estava disponível na data em que o arquivo foi publicado. O arquivo está armazenado em servidores com segurança avançada que ajudam a evitar qualquer alteração não autorizada no arquivo.

Para obter o bloco XML que contém essa DataTable, posso usar o código a seguir:
objNodeList = objXmlDoc.getElementsByTagName("Categories");
Isso retorna um objeto IXMLDOMNodeList que contém cada nó <Categories>. Eu, em seguida, percorrer essa lista usando um loop for.</Categories>
// walk through the nodeList and populate the drop-down
  for (var i = 0; i < objNodeList.length; i++) 
  {
      var dataNodeList;
      var textNode;
      var valueNode;

      dataNodeList = objNodeList[i].childNodes;
      valueNode = dataNodeList.item(0);
      textNode = dataNodeList.item(1);

      document.forms[0].drpCategory.options[i + 1] = 
new Option(textNode.text, valueNode.text);
      document.all.lblCategoryDropdown.innerText = "Select a Category:";
      document.forms[0].drpCategory.style.visibility = "visible";
       
    }
Já sei que cada nó <Categories>terá dois nós que preciso: o nó de <ID>e o <CategoryName>. Portanto, a primeira coisa a fazer é criar um novo IXMLDOMNodeList e preenchê-lo com os nós filhos do atual <Categories>nó.</Categories> </CategoryName> </ID> </Categories>
dataNodeList = objNodeList[i].childNodes;
Em seguida, uso o método item para acessar ambos os nós que eu precise preencher meu drop-down. O primeiro nó contém o campo CódigoDaCategoria do banco de dados e o segundo nó contém o campo NomeDaCategoria do banco de dados. Criar um novo objeto de opção , defina o texto para o NomeDaCategoria, defina o valor para o CategoryIDe adicioná-lo à drpCategory drop-down. O código que é usado em funções restantes usa o mesmo método para extrair os dados necessários da resposta XML e preencher partes da página.

Observação Como estamos lidando com pequenas quantidades de dados aqui, usando o DOM é uma ótima maneira de retirar os dados que precisamos. Se você estivesse lidando com uma grande quantidade de dados, você pode optar por usar o XSLT.

Como fazer tudo funcionar

Agora que tratei dos detalhes de como tudo isso funciona, é hora de falar sobre como você pode usar os arquivos de exemplo incluído para vê-lo a trabalhar por conta própria.

Implantando o serviço da Web

Para implantar o serviço da Web do ASP.NET, simplesmente descompacte o exemplo de serviço da Web anexado à raiz do seu servidor Web. Em seguida, será necessário abrir o código para DynaProducts.asmx e altere a seqüência de conexão. No mínimo, você precisará digitar a senha do SA. Após fazer essa alteração, recompile o serviço da Web.

Implantação do arquivo HTML

O arquivo HTML contém uma variável chamada szUrl que contém uma URL para o serviço da Web. Você encontrará essa variável na função getDataFromWS na parte inferior da função. Você precisará alterá-la para a URL do serviço da Web implantados acima.

Depois que tiver implantado o serviço da Web e o arquivo HTML, procure o arquivo HTML. Ao ser carregado, na lista suspensa categoria será preenchida com a primeira solicitação XMLHTTP para o serviço da Web. Uma vez que foi preenchido, selecione uma categoria para disparar a próxima solicitação XMLHTTP que preenche a listas suspensa de produtos. Selecionar um produto na lista suspensa produtos irá preencher uma tabela com dados sobre o produto.

Observe que a página não postar novamente durante qualquer uma dessas solicitações XMLHTTP. Essa é a vantagem de solicitações XMLHTTP. Se tivesse feito isso em uma página grande, a página seria ter também mantido sua posição de rolagem sem "piscando" ao usuário. Se você me perguntar, que é algo muito poderoso!

Mais uma coisa: neste artigo, usei XMLHTTP para consultar um serviço da Web. Eu poderia ter facilmente usado ele para fazer uma solicitação para uma página ASPX ou uma página ASP. As possibilidades de como você pode colocar essa tecnologia para uso são infinitas. Espero que você úteis XMLHTTP no seu futuro desenvolvimento de aplicativos da Web.
Como sempre, fique à vontade para enviar idéias sobre tópicos desejado no futuro abordada colunas ou na Base de dados de Conhecimento da Microsoft usando o Peça para ele formulário.

Propriedades

ID do artigo: 893659 - Última revisão: sexta-feira, 28 de junho de 2013 - Revisão: 6.0
A informação contida neste artigo aplica-se a:
  • Microsoft ASP.NET 1.0
  • Microsoft ASP.NET 1.1
Palavras-chave: 
kbgraphic kbscript kbxml kbhowto kbmt KB893659 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido pelo software de tradução automática da Microsoft e eventualmente pode ter sido editado pela Microsoft Community através da tecnologia Community Translation Framework (CTF) ou por um tradutor profissional. A Microsoft oferece artigos traduzidos automaticamente por software, por tradutores profissionais e editados pela comunidade para que você tenha acesso a todos os artigos de nossa Base de Conhecimento em diversos idiomas. No entanto, um artigo traduzido pode conter erros de vocabulário, sintaxe e/ou gramática. A Microsoft não é responsável por qualquer inexatidão, erro ou dano causado por qualquer tradução imprecisa do conteúdo ou por seu uso pelos nossos clientes.
Clique aqui para ver a versão em Inglês deste artigo: 893659

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com