Compartilhar via


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

  1. 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.

  2. 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.

  3. Coloque a classe ProductQueryService em um namespace chamado Samples.

  4. Adicione o atributo ScriptServiceAttribute à classe.

    Esse atributo permite que o serviço Web para ser chamado de um script de cliente.

  5. 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.

  6. Salve suas alterações e, em seguida, pressione CTRL + F5 para exibir a página em um navegador.

  7. Clique no link GetProductQuantity para invocar o método Web.

  8. 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

  1. Crie um novo arquivo JScript denominado ProductQueryScript.js.

  2. 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

  1. Crie uma nova página Web e alterne para modo de Design.

  2. Na guia Extensões AJAX da caixa de ferramentas, clique duas vezes no controle ScriptManager para adicioná-lo à página.

  3. Clique duas vezes no controle UpdatePanel na barra de ferramentas para adicioná um controle UpdatePanel à página da Web.

  4. Clique dentro do controle UpdatePanel e, em seguida, na guia Dados da caixa de ferramentas, clique duas vezes no controle DataList.

  5. 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.

  6. Selecione Banco de Dados, aceite o nome padrão SqlDataSource1 e em seguida, clique em OK.

  7. 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.

  8. 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.

  9. Clique no botão WHERE.

    A caixa de diálogo Add WHERE Clause é exibida.

  10. Na lista Columns, selecione CategoryID e na lista de Fonte, selecione Nenhum.

  11. Na seção Propriedades do Parâmetro da caixa de diálogo, na caixa de texto Valor, digite 1.

  12. Clique Adicionar para adicionar a cláusula WHERE na instrução SQL.

  13. Clique em OK para fechar a caixa de diálogo Add WHERE Clause.

  14. Clique em Avançar, e clique em Concluir para fechar o assistente.

  15. 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>
    
  16. Alternar para modo Design.

  17. Selecione o controle DataList e no painel Tarefas DataList, clique em Editar Modelos.

  18. Adicionar dois controles Button ao controle UpdatePanel fora do controle DataList.

  19. 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.

  20. selecionar o UpdatePanel controle e na janela Propriedades, conjunto o UpdateMode propriedade para Conditional e conjunto o ChildrenAsTriggers propriedade para false.

  21. 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.

  22. 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.

  23. 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.

  24. Salve suas alterações e, em seguida, pressione CTRL + F5 para exibir a página em um navegador.

  25. 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

  1. Na página, alterne para modo de design.

  2. Selecione o controle DataList e no painel Tarefas DataList, clique em Editar Modelos.

  3. Adicione um controle TextBox e um Button no modelo de item.

    Adicione os novos controles sob o texto e rótulos existentes no modelo.

  4. 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.

  5. Selecione o controle DataList e em seguida, na guia Eventos da janela Propriedades, clique duas vezes no evento ItemDataBound.

  6. 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.

  7. 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.

  8. 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.

  9. Alternar para modo Design.

  10. Selecione o controle ScriptManager.

  11. 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 .

  12. Clique em Adicionar para adicionar um serviço de referência.

  13. 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.

  14. Clique em OK para fechar a caixa de diálogo Editor de Coleção ListItem.

  15. 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.

  16. Clique em Adicionar para adicionar uma referência de script.

  17. 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.

  18. Clique em OK para fechar a caixa de diálogo Editor de Coleção ScriptReference.

  19. 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

  1. Se a página não estiver em execução, pressione CTRL + F5 para executar a página.

  2. 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.

  3. clicar no botão da categoria 2.

  4. 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.

Consulte também

Conceitos

Expondo Serviços Web a Script Cliente

Chamando Serviços da Web de Scripts Clientes