Usando o Controle UpdatePanel com um Serviço da Web
O controle UpdatePanel simplifica a renderização parcial de página em páginas da Web ASP.NET porque a funcionalidade AJAX do ASP.NET gerencia solicitações postback assíncronas e atualiza automaticamente.A funcionalidade AJAX também permite que você chamar serviços da Web ASP.NET usando ECMAScript (JavaScript) no navegador.Uma das vantagens de chamar um serviço Web usando script de cliente é que a espera pela resposta de uma solicitação de um serviço Web não bloqueará o navegador.Os usuários podem continuar a trabalhar sem aguardar que o serviço Web conclua o processamento da solicitação.
Este tutorial mostra como usar um serviço Web usando um controle UpdatePanel.Uma função JavaScript chama o serviço Web para recuperar dados para, em seguida, preencher os elementos DOM em um controle UpdatePanel com dados retornados a partir de serviço Web.Código de servidor preserva os dados de serviço Web recuperados entre postagens assíncronas.
Este tópico pressupõe que você é familiarizado com o controle UpdatePanel e serviços da Web.Se não estiver, revise os seguintes tópicos:
Pré-requisitos
Para implementar os procedimentos no seu próprio ambiente de desenvolvimento você precisa:
Microsoft Visual Studio 2005 ou Visual Web Developer Express Edition.
Um site da Web ASP.NET habilitado para AJAX.
O acesso a banco de dados Northwind e uma cadeia de caracteres de conexão chamado NorthwindConnectionString definidos no arquivo Web.config.Para obter informações adicionais sobre como criar um cadeia de caracteres de conexão, consulte Como: Ler as seqüências de conexão do arquivo Web.config.
Criando um serviço da Web
Para começar, você criará um serviço Web que você pode chamar.
Para criar um serviço Web para retornar quantidades de produtos
Em um site ASP.NET com AJAX habilitado, crie um novo arquivo de serviço Web denominado ProductQueryService.asmx.
Para obter informações adicionais sobre como criar um serviço Web, consulte Chamando Serviços da Web de Scripts Clientes.
No código serviço Web, importar os namespaces N:System.Data, N:System.Data.SqlClient, System.Configuration e N:System.Web.Script.Services.
Imports System.Data Imports System.Data.SqlClient Imports System.Configuration Imports System.Web.Script.Services
using System.Web.Script.Services; using System.Data; using System.Data.SqlClient; using System.Configuration;
Tipos desses namespaces serão usados no método do serviço Web que você irá criar.
Coloque a classe ProductQueryService em um namespace chamado Samples.
Adicione o atributo ScriptServiceAttribute à classe.
Esse atributo permite que o serviço Web para ser chamado de um script de cliente.
Substitua o método HelloWorld padrão pelo seguinte método GetProductQuantity.
<WebMethod()> _ Public Function GetProductQuantity(ByVal productID As String) As String Dim cn As SqlConnection = _ New SqlConnection(ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString) Dim cmd As SqlCommand = _ New SqlCommand("SELECT [UnitsInStock] FROM [Alphabetical list of products] WHERE ([ProductID] = @ProductID)", cn) cmd.Parameters.AddWithValue("productID", productID) Dim unitsInStock As String = "" cn.Open() Using dr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection) Do While dr.Read() unitsInStock = dr(0).ToString() Loop End Using System.Threading.Thread.Sleep(3000) Return unitsInStock End Function
[WebMethod] public string GetProductQuantity(string productID) { SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString); SqlCommand cmd = new SqlCommand( "SELECT [UnitsInStock] FROM [Alphabetical list of products] WHERE ([ProductID] = @ProductID)", cn); cmd.Parameters.Add("productID", productID); String unitsInStock = ""; cn.Open(); using (SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) { while (dr.Read()) unitsInStock = dr[0].ToString(); } System.Threading.Thread.Sleep(3000); return unitsInStock; }
O código executa as seguintes tarefas:
Cria um novo objeto SqlConnection que usa uma cadeia de caracteres de conexão chamado NorthwindConnectionString.
Cria um novo objeto SqlCommand que contém um comando SQL para recuperar o número de unidades em estoque para um certo ID de produto.
Define o valor de retorno para uma cadeia de caracteres que é usada como a resposta que é enviada ao navegador.
Observação: Para este tutorial, o método Web apresenta um atraso artificial.Na prática, você poderia não introduzir um atraso.Em vez disso, qualquer atraso deve ser o resultado do tráfego do servidor Web ou do código que demora para processar, como uma consulta ao banco de dados de execução demorada.
Salve suas alterações e, em seguida, pressione CTRL + F5 para exibir a página em um navegador.
Clique no link GetProductQuantity para invocar o método Web.
Digite 6 na caixa de idProduto e, em seguida, clique em Chamar.
A quantidade do produto é retornada como XML no navegador.Isso demonstra que o serviço Web está funcionando conforme o esperado.
<%@ WebService Language="VB" Class="Samples.ProductQueryService" %> Imports System Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols Imports System.Data Imports System.Data.SqlClient Imports System.Configuration Imports System.Web.Script.Services Namespace Samples <ScriptService()> _ <WebService(Namespace:="http://tempuri.org/")> _ <WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _ Public Class ProductQueryService Inherits System.Web.Services.WebService <WebMethod()> _ Public Function GetProductQuantity(ByVal productID As String) As String Dim cn As SqlConnection = _ New SqlConnection(ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString) Dim cmd As SqlCommand = _ New SqlCommand("SELECT [UnitsInStock] FROM [Alphabetical list of products] WHERE ([ProductID] = @ProductID)", cn) cmd.Parameters.AddWithValue("productID", productID) Dim unitsInStock As String = "" cn.Open() Using dr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection) Do While dr.Read() unitsInStock = dr(0).ToString() Loop End Using System.Threading.Thread.Sleep(3000) Return unitsInStock End Function End Class End Namespace
<%@ WebService Language="C#" Class="Samples.ProductQueryService" %> using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.Web.Script.Services; using System.Data; using System.Data.SqlClient; using System.Configuration; namespace Samples { [ScriptService] [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class ProductQueryService : System.Web.Services.WebService { [WebMethod] public string GetProductQuantity(string productID) { SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString); SqlCommand cmd = new SqlCommand( "SELECT [UnitsInStock] FROM [Alphabetical list of products] WHERE ([ProductID] = @ProductID)", cn); cmd.Parameters.Add("productID", productID); String unitsInStock = ""; cn.Open(); using (SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) { while (dr.Read()) unitsInStock = dr[0].ToString(); } System.Threading.Thread.Sleep(3000); return unitsInStock; } } }
Criando código de JavaScript para chamar o serviço da Web
Neste procedimento você criará um arquivo de JavaScript que chama o serviço Web que você criou no procedimento anterior.
Para criar um arquivo de JavaScript para usar o serviço da Web
Crie um novo arquivo JScript denominado ProductQueryScript.js.
Adicione o seguinte script ao arquivo:
function GetQuantity(productID, elemToUpdate, productLabelElem, buttonElem) { var userContext = [productID, elemToUpdate, productLabelElem, buttonElem]; Samples.ProductQueryService.GetProductQuantity(productID, OnSucceeded, null, userContext, null); $get(buttonElem).value = "Retrieving value..."; } function OnSucceeded(result, userContext) { var productID = userContext[0]; var elemToUpdate = userContext[1]; var productLabelElem = userContext[2]; var buttonElem = userContext[3]; $get(buttonElem).value = "Get Quantity from Web Service"; if ($get(elemToUpdate) !== null && $get(productLabelElem).innerHTML == productID) { $get(elemToUpdate).value = result; } }
function GetQuantity(productID, elemToUpdate, productLabelElem, buttonElem) { var userContext = [productID, elemToUpdate, productLabelElem, buttonElem]; Samples.ProductQueryService.GetProductQuantity(productID, OnSucceeded, null, userContext, null); $get(buttonElem).value = "Retrieving value..."; } function OnSucceeded(result, userContext) { var productID = userContext[0]; var elemToUpdate = userContext[1]; var productLabelElem = userContext[2]; var buttonElem = userContext[3]; $get(buttonElem).value = "Get Quantity from Web Service"; if ($get(elemToUpdate) !== null && $get(productLabelElem).innerHTML == productID) { $get(elemToUpdate).value = result; } }
O script executa as seguintes tarefas:
Cria uma função chamada GetQuantity que chama o método de serviço Web GetProductQuantity.
Cria uma função chamada OnSucceeded que é invocada quando a chamada serviço Web retorna com um resultado.
Criando uma página da Web para exibir dados
Em seguida, você criará um página da Web que contém um controle UpdatePanel.Os controles dentro do controle UpdatePanel exibem informações do produto do banco de dados Northwind.
Para criar um página da Web para exibir produtos
Crie uma nova página Web e alterne para modo de Design.
Na guia Extensões AJAX da caixa de ferramentas, clique duas vezes no controle ScriptManager para adicioná-lo à página.
Clique duas vezes no controle UpdatePanel na barra de ferramentas para adicioná um controle UpdatePanel à página da Web.
Clique dentro do controle UpdatePanel e, em seguida, na guia Dados da caixa de ferramentas, clique duas vezes no controle DataList.
No painel Tarefas DataList, da lista Escolher Fonte de Dados lista, selecione <Nova fonte de dados… >.
Observação: Se você não ver o painel Tarefas DataList, clique com o botão direito do mouse no controle DataList e selecione Mostrar Smart Tag.
O assistente Configração da Fonte de Dados é exibido.
Selecione Banco de Dados, aceite o nome padrão SqlDataSource1 e em seguida, clique em OK.
Na lista Que conexão de dados o aplicativo deve usar para se conectar ao banco de dados, selecione NorthwindConnectionString e em seguida, clique em Avançar.
Em Como você deseja que recuperar os dados de seu banco de dados, selecione Especificar colunas de uma tabela ou modo de exibição, selecione Products a partir da lista e na lista Columns, selecione ProductID e ProductName.
Clique no botão WHERE.
A caixa de diálogo Add WHERE Clause é exibida.
Na lista Columns, selecione CategoryID e na lista de Fonte, selecione Nenhum.
Na seção Propriedades do Parâmetro da caixa de diálogo, na caixa de texto Valor, digite 1.
Clique Adicionar para adicionar a cláusula WHERE na instrução SQL.
Clique em OK para fechar a caixa de diálogo Add WHERE Clause.
Clique em Avançar, e clique em Concluir para fechar o assistente.
Alterne para Modo de exibição Source e confirmar que o controle SqlDataSource lembra o exemplo a seguir:
<asp:SqlDataSource ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT [ProductName], [ProductID] FROM [Alphabetical list of products] WHERE ([CategoryID] = @CategoryID)"> <SelectParameters> <asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" /> </SelectParameters> </asp:SqlDataSource>
<asp:SqlDataSource ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT [ProductName], [ProductID] FROM [Alphabetical list of products] WHERE ([CategoryID] = @CategoryID)"> <SelectParameters> <asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" /> </SelectParameters> </asp:SqlDataSource>
Alternar para modo Design.
Selecione o controle DataList e no painel Tarefas DataList, clique em Editar Modelos.
Adicionar dois controles Button ao controle UpdatePanel fora do controle DataList.
ID propriedade para Category1Button and its Text propriedade para a categoria 1. conjunto ID propriedade para Category2Button and its Text propriedade para a categoria 2.
selecionar o UpdatePanel controle e na janela Propriedades, conjunto o UpdateMode propriedade para Conditional e conjunto o ChildrenAsTriggers propriedade para false.
Na caixa Disparadores, clique no botão reticências (…) e na caixa de diálogo Editor de Coleção de Disparadores UpdatePanel, adicione cada botão de categoria como um disparador postback assíncrono.
Defina o manipulador de eventos Click para o primeiro botão BotãoCategoria1_Clique e o manipulador de eventos Click para o segundo botão BotãoCategoria2_Clique.
Alterne para Modo de exibição Source e crie os manipuladores de eventos a seguir para os dois botões:
Protected Sub Category1Button_Click(ByVal sender As Object, ByVal e As System.EventArgs) SqlDataSource1.SelectParameters(0).DefaultValue = "1" End Sub Protected Sub Category2Button_Click(ByVal sender As Object, ByVal e As System.EventArgs) SqlDataSource1.SelectParameters(0).DefaultValue = "2" End Sub
protected void Category1Button_Click(object sender, EventArgs e) { SqlDataSource1.SelectParameters[0].DefaultValue = "1"; } protected void Category2Button_Click(object sender, EventArgs e) { SqlDataSource1.SelectParameters[0].DefaultValue = "2"; }
O código manipulador de eventos define o parâmetro CategoryID da coleção SelectParameters no controle SqlDataSource, com base em qual botão foi pressionado.Isso permite que os usuários alternem entre duas categorias.
Salve suas alterações e, em seguida, pressione CTRL + F5 para exibir a página em um navegador.
clicar categoria 2 e verificar se a página exibe novas informações mas não atualiza a página inteira.
Observação: Não feche a página.
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > Protected Sub Category1Button_Click(ByVal sender As Object, ByVal e As System.EventArgs) SqlDataSource1.SelectParameters(0).DefaultValue = "1" End Sub Protected Sub Category2Button_Click(ByVal sender As Object, ByVal e As System.EventArgs) SqlDataSource1.SelectParameters(0).DefaultValue = "2" End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head > <title>Products Display</title> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" > </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" ChildrenAsTriggers="False" UpdateMode="Conditional"> <ContentTemplate> <asp:Button ID="Category1Button" Text="Category 1" OnClick="Category1Button_Click" /> <asp:Button ID="Category2Button" OnClick="Category2Button_Click" Text="Category 2" /> <asp:DataList ID="DataList1" DataKeyField="ProductID" DataSourceID="SqlDataSource1" Width="231px"> <ItemTemplate> ProductName: <asp:Label ID="ProductNameLabel" Text='<%# Eval("ProductName") %>'> </asp:Label><br /> ProductID: <asp:Label ID="ProductIDLabel" Text='<%# Eval("ProductID") %>'></asp:Label><br /> <br /> </ItemTemplate> </asp:DataList> <asp:SqlDataSource ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT [ProductName], [ProductID] FROM [Alphabetical list of products] WHERE ([CategoryID] = @CategoryID)"> <SelectParameters> <asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" /> </SelectParameters> </asp:SqlDataSource> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Category1Button" /> <asp:AsyncPostBackTrigger ControlID="Category2Button" /> </Triggers> </asp:UpdatePanel> </div> </form> </body> </html>
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > protected void Category1Button_Click(object sender, EventArgs e) { SqlDataSource1.SelectParameters[0].DefaultValue = "1"; } protected void Category2Button_Click(object sender, EventArgs e) { SqlDataSource1.SelectParameters[0].DefaultValue = "2"; } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head > <title>Products Display</title> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" > </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" ChildrenAsTriggers="False" UpdateMode="Conditional"> <ContentTemplate> <asp:Button ID="Category1Button" Text="Category 1" OnClick="Category1Button_Click" /> <asp:Button ID="Category2Button" OnClick="Category2Button_Click" Text="Category 2" /> <asp:DataList ID="DataList1" DataKeyField="ProductID" DataSourceID="SqlDataSource1" Width="231px"> <ItemTemplate> ProductName: <asp:Label ID="ProductNameLabel" Text='<%# Eval("ProductName") %>'> </asp:Label><br /> ProductID: <asp:Label ID="ProductIDLabel" Text='<%# Eval("ProductID") %>'></asp:Label><br /> <br /> </ItemTemplate> </asp:DataList> <asp:SqlDataSource ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT [ProductName], [ProductID] FROM [Alphabetical list of products] WHERE ([CategoryID] = @CategoryID)"> <SelectParameters> <asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" /> </SelectParameters> </asp:SqlDataSource> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Category1Button" /> <asp:AsyncPostBackTrigger ControlID="Category2Button" /> </Triggers> </asp:UpdatePanel> </div> </form> </body> </html>
Chamando um serviço da Web para recuperar os dados
Agora você chamará o serviço Web, utilizando o arquivo JavaScript que você criou anteriormente.O código JavaScript usa os dados retornados para preencher o elementos DOM dentro do controle UpdatePanel.Código de servidor na página preserva os dados que são preenchidos a partir do serviço Web e adiciona os dados no estado de exibição da página.Isso mantém os dados em quaisquer postagens assíncronas subsequentes.
Para usar um serviço Web para retornar quantidades de produtos
Na página, alterne para modo de design.
Selecione o controle DataList e no painel Tarefas DataList, clique em Editar Modelos.
Adicione um controle TextBox e um Button no modelo de item.
Adicione os novos controles sob o texto e rótulos existentes no modelo.
selecionar o botão e na janela Propriedades, conjunto seus Text propriedade Get quantidade do serviço Web.
O modelo de item do controle DataList deve se parecer com a figura a seguir.
Selecione o controle DataList e em seguida, na guia Eventos da janela Propriedades, clique duas vezes no evento ItemDataBound.
Adicione o seguinte código:
Protected Sub DataList1_ItemDataBound(ByVal sender As Object, ByVal e As DataListItemEventArgs) Dim label As Label = CType(e.Item.FindControl("ProductIDLabel"), Label) Dim button As Button = CType(e.Item.FindControl("Button1"), Button) Dim textbox As TextBox = CType(e.Item.FindControl("TextBox1"), TextBox) button.OnClientClick = "GetQuantity(" & label.Text & ",'" & textbox.ClientID & "','" & _ label.ClientID + "','" & button.ClientID & "')" Dim ProductInfo As SortedList = Me.ProductInfo If (ProductInfo.ContainsKey(label.Text)) Then textbox.Text = ProductInfo(label.Text).ToString() End If End Sub
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e) { Label label = (Label)e.Item.FindControl("ProductIDLabel"); Button button = (Button)e.Item.FindControl("Button1"); TextBox textbox = (TextBox)e.Item.FindControl("TextBox1"); button.OnClientClick = "GetQuantity(" + label.Text + ",'" + textbox.ClientID + "','" + label.ClientID + "','" + button.ClientID + "')"; SortedList ProductInfo = this.ProductInfo; if (ProductInfo.ContainsKey(label.Text)) { textbox.Text = ProductInfo[label.Text].ToString(); } }
O código define propriedades para controles em cada objeto DataListItem da seguinte maneira:
A propriedade do botão OnClientClick chama uma função JavaScript que por sua vez chama o serviço Web.
O valor da caixa de texto é definido se uma propriedade de acompanhamento de chamada ProductInfo contém uma chave para a ID do produto. The ProductInfo propriedade é definida na próxima etapa deste procedimento.
Adicione uma propriedade chamada ProductInfo à página mestra.
Protected Property ProductInfo() As SortedList Get If ViewState("ProductInfo") IsNot Nothing Then Return CType(ViewState("ProductInfo"), SortedList) Else Return New SortedList() End If End Get Set(ByVal value As SortedList) ViewState("ProductInfo") = value End Set End Property
protected SortedList ProductInfo { get { return (SortedList)(ViewState["ProductInfo"] ?? new SortedList()); } set { ViewState["ProductInfo"] = value; } }
Esta propriedade é um objeto SortedList que rastreia dados que são adicionados à página a partir do serviço Web.Na primeira vez que a página é processada, a lista está vazia.Durante postbacks assíncronos subsequentes, itens podem ser adicionados à lista.
Adicione o seguinte manipulador de eventos Page_Load:
Protected Sub Page_Load() If (ScriptManager1.IsInAsyncPostBack) Then Dim ProductInfo As SortedList = Me.ProductInfo For Each d As DataListItem In DataList1.Items Dim label As Label = CType(d.FindControl("ProductIDLabel"), Label) Dim textbox As TextBox = CType(d.FindControl("TextBox1"), TextBox) If (textbox.Text.Length > 0) Then ProductInfo(label.Text) = textbox.Text End If Next Me.ProductInfo = ProductInfo End If End Sub
protected void Page_Load(object sender, EventArgs e) { if (ScriptManager1.IsInAsyncPostBack) { SortedList ProductInfo = this.ProductInfo; foreach (DataListItem d in DataList1.Items) { Label label = (Label)d.FindControl("ProductIDLabel"); TextBox textbox = (TextBox)d.FindControl("TextBox1"); if (textbox.Text.Length > 0) { ProductInfo[label.Text] = textbox.Text; } } this.ProductInfo = ProductInfo; } }
O código verifica se a solicitação é um postback assíncrono.Se for, quaisquer itens de dados que são adicionados pelo serviço Web são adicionados à propriedade ProductInfo.Isso permite que eles serem rastreadas no estado de exibição e exibidos na caixa UpdatePanel durante atualizações parciais de página subsequentes.Se os itens de dados não são controlados em estado de exibição, eles não são mantidos em postagens assíncronas subsequentes.
Alternar para modo Design.
Selecione o controle ScriptManager.
Na janela Propriedades, selecione a propriedade Serviços e clique no botão reticências (…) para exibir a caixa de diálogo Editor de Coleção ServiceReference .
Clique em Adicionar para adicionar um serviço de referência.
Defina a propriedade Caminho da referência de serviço para ProductQueryService.asmx, que é a serviço Web que você criou anteriormente.
Adicionando uma referência de serviço faz com que o controle ScriptManager gere classes proxy do cliente para que o serviço Web possa ser chamado usando JavaScript.
Clique em OK para fechar a caixa de diálogo Editor de Coleção ListItem.
Selecione o controle ScriptManager e em seguida, na janela Propriedades, selecione a propriedade Scripts e clique no botão reticências (…) para exibir a caixa de diálogo Editor de Coleção ScriptReference.
Clique em Adicionar para adicionar uma referência de script.
Defina a propriedade Caminho da referência de script para ProductQueryScript.js, que é o arquivo de JavaScript que você criou anteriormente.
Adicionar uma referência de script faz com que o controle ScriptManager insira o script após o Microsoft AJAX Library ser carregado.
Clique em OK para fechar a caixa de diálogo Editor de Coleção ScriptReference.
Salve suas alterações e, em seguida, pressione CTRL + F5 para exibir a página em um navegador.
A página mostra os produtos do banco de dados Northwind cuja ID de categoria é 1.As caixas de texto ao lado de cada produto estão vazias, porque não há chamadas de serviço Web tenham sido feitas.
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > Protected Property ProductInfo() As SortedList Get If ViewState("ProductInfo") IsNot Nothing Then Return CType(ViewState("ProductInfo"), SortedList) Else Return New SortedList() End If End Get Set(ByVal value As SortedList) ViewState("ProductInfo") = value End Set End Property Protected Sub Category1Button_Click(ByVal sender As Object, ByVal e As EventArgs) SqlDataSource1.SelectParameters(0).DefaultValue = "1" End Sub Protected Sub Category2Button_Click(ByVal sender As Object, ByVal e As EventArgs) SqlDataSource1.SelectParameters(0).DefaultValue = "2" End Sub Protected Sub DataList1_ItemDataBound(ByVal sender As Object, ByVal e As DataListItemEventArgs) Dim label As Label = CType(e.Item.FindControl("ProductIDLabel"), Label) Dim button As Button = CType(e.Item.FindControl("Button1"), Button) Dim textbox As TextBox = CType(e.Item.FindControl("TextBox1"), TextBox) button.OnClientClick = "GetQuantity(" & label.Text & ",'" & textbox.ClientID & "','" & _ label.ClientID + "','" & button.ClientID & "')" Dim ProductInfo As SortedList = Me.ProductInfo If (ProductInfo.ContainsKey(label.Text)) Then textbox.Text = ProductInfo(label.Text).ToString() End If End Sub Protected Sub Page_Load() If (ScriptManager1.IsInAsyncPostBack) Then Dim ProductInfo As SortedList = Me.ProductInfo For Each d As DataListItem In DataList1.Items Dim label As Label = CType(d.FindControl("ProductIDLabel"), Label) Dim textbox As TextBox = CType(d.FindControl("TextBox1"), TextBox) If (textbox.Text.Length > 0) Then ProductInfo(label.Text) = textbox.Text End If Next Me.ProductInfo = ProductInfo End If End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head > <title>Products Display</title> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" > <Services> <asp:ServiceReference Path="ProductQueryService.asmx" /> </Services> <Scripts> <asp:ScriptReference Path="ProductQueryScript.js" /> </Scripts> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" ChildrenAsTriggers="False" UpdateMode="Conditional"> <ContentTemplate> <asp:Button ID="Category1Button" Text="Category 1" OnClick="Category1Button_Click" /> <asp:Button ID="Category2Button" OnClick="Category2Button_Click" Text="Category 2" /> <asp:DataList ID="DataList1" DataKeyField="ProductID" DataSourceID="SqlDataSource1" Width="400px" OnItemDataBound="DataList1_ItemDataBound"> <ItemTemplate> ProductName: <asp:Label ID="ProductNameLabel" Text='<%# Eval("ProductName") %>'> </asp:Label><br /> ProductID: <asp:Label ID="ProductIDLabel" Text='<%# Eval("ProductID") %>'></asp:Label><br /> <asp:TextBox ID="TextBox1" ></asp:TextBox> <asp:Button ID="Button1" Text="Get Quantity from Web Service" /><br /> </ItemTemplate> </asp:DataList> <asp:SqlDataSource ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT [ProductName], [ProductID] FROM [Alphabetical list of products] WHERE ([CategoryID] = @CategoryID)"> <SelectParameters> <asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" /> </SelectParameters> </asp:SqlDataSource> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Category1Button" /> <asp:AsyncPostBackTrigger ControlID="Category2Button" /> </Triggers> </asp:UpdatePanel> </div> </form> </body> </html>
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > protected SortedList ProductInfo { get { return (SortedList)(ViewState["ProductInfo"] ?? new SortedList()); } set { ViewState["ProductInfo"] = value; } } protected void Category1Button_Click(object sender, EventArgs e) { SqlDataSource1.SelectParameters[0].DefaultValue = "1"; } protected void Category2Button_Click(object sender, EventArgs e) { SqlDataSource1.SelectParameters[0].DefaultValue = "2"; } protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e) { Label label = (Label)e.Item.FindControl("ProductIDLabel"); Button button = (Button)e.Item.FindControl("Button1"); TextBox textbox = (TextBox)e.Item.FindControl("TextBox1"); button.OnClientClick = "GetQuantity(" + label.Text + ",'" + textbox.ClientID + "','" + label.ClientID + "','" + button.ClientID + "')"; SortedList ProductInfo = this.ProductInfo; if (ProductInfo.ContainsKey(label.Text)) { textbox.Text = ProductInfo[label.Text].ToString(); } } protected void Page_Load(object sender, EventArgs e) { if (ScriptManager1.IsInAsyncPostBack) { SortedList ProductInfo = this.ProductInfo; foreach (DataListItem d in DataList1.Items) { Label label = (Label)d.FindControl("ProductIDLabel"); TextBox textbox = (TextBox)d.FindControl("TextBox1"); if (textbox.Text.Length > 0) { ProductInfo[label.Text] = textbox.Text; } } this.ProductInfo = ProductInfo; } } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head > <title>Products Display</title> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" > <Services> <asp:ServiceReference Path="ProductQueryService.asmx" /> </Services> <Scripts> <asp:ScriptReference Path="ProductQueryScript.js" /> </Scripts> </asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" ChildrenAsTriggers="False" UpdateMode="Conditional"> <ContentTemplate> <asp:Button ID="Category1Button" Text="Category 1" OnClick="Category1Button_Click" /> <asp:Button ID="Category2Button" OnClick="Category2Button_Click" Text="Category 2" /> <asp:DataList ID="DataList1" DataKeyField="ProductID" DataSourceID="SqlDataSource1" Width="400px" OnItemDataBound="DataList1_ItemDataBound"> <ItemTemplate> ProductName: <asp:Label ID="ProductNameLabel" Text='<%# Eval("ProductName") %>'> </asp:Label><br /> ProductID: <asp:Label ID="ProductIDLabel" Text='<%# Eval("ProductID") %>'></asp:Label><br /> <asp:TextBox ID="TextBox1" ></asp:TextBox> <asp:Button ID="Button1" Text="Get Quantity from Web Service" /><br /> </ItemTemplate> </asp:DataList> <asp:SqlDataSource ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT [ProductName], [ProductID] FROM [Alphabetical list of products] WHERE ([CategoryID] = @CategoryID)"> <SelectParameters> <asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" /> </SelectParameters> </asp:SqlDataSource> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Category1Button" /> <asp:AsyncPostBackTrigger ControlID="Category2Button" /> </Triggers> </asp:UpdatePanel> </div> </form> </body> </html>
Verificando se os dados são persistidos durante postbacks assíncronos
Agora você pode ver como dados de serviço Web são mantidos durante postbacks assíncronos.
Para verificar que os dados do serviço Web são mantidos durante postagens assíncronas
Se a página não estiver em execução, pressione CTRL + F5 para executar a página.
clicar na quantidade de obter no botão de serviço Web para qualquer produto na lista e aguarde o valor a ser exibido na caixa de texto.
clicar no botão da categoria 2.
clicar no botão da categoria 1.
Observe que o valor que foi retornado anteriormente pela serviço Web ainda é exibido, mesmo após os postbacks assíncronos.
Revisão
Neste tutorial, mostramos um exemplo de como usar um controle UpdatePanel com um serviço Web que é chamado pelo código JavaScript no navegador.O serviço Web retorna dados que são exibidos dentro do controle UpdatePanel.
O resultado de chamar o serviço Web a partir de script de cliente e preenchendo elementos DOM usando os dados retornados é o mesmo com ou sem controles UpdatePanel.Quando uma página executa um postback ou quando ocorre um postback assíncrono, os dados que anteriormente eram exibidos usando script de cliente são perdidos.Para evitar esse problema, você pode usar código de servidor para manter os dados tornando-os parte do estado de exibição.Isso permite que você mantenha os dados durante postbacks subsequentes.Se os dados do serviço Web forem exibidos em elementos DOM fora dos controles UpdatePanel e você não deseja persistir os dados durante postagens assíncronas, você não precisará fornecer código do servidor para mantê-lo.
Como o botão que disparou a chamada serviço Web está dentro do controle UpdatePanel, a propriedade ChildrenAsTriggers é definida como false.Outros controles de postback dentro painel são definidos como disparadores para o painel.