Documentation for: ASP.NET Ajax Version 1.0

This documentation is for a previous version. For the current released version, see the ASP.NET Ajax documentation on MSDN.

 

 

 

 

 

 

 

Skip Navigation Links.
Tutorials
Sample ASP.NET AJAX Application
ASP.NET AJAX and JavaScript
Extending JavaScript with ASP.NET AJAX
Creating Custom Client Script in ASP.NET AJAX
Dynamically Assigning ASP.NET AJAX Script References
Globalizing a Date by Using Client Script
Embedding a JavaScript File as a Resource in an Assembly
Embedding Localized Resources for a JavaScript File
Adding Localized Resources to a JavaScript File
Creating Custom Client Events
The UpdatePanel Control
Introduction to the UpdatePanel Control
Creating a Simple ASP.NET Page with Multiple UpdatePanel Controls
Using the UpdatePanel Control with Data-Bound Controls
Using the UpdatePanel Control with Master Pages
Using the UpdatePanel Control with User Controls
Using the UpdatePanel Control with a Web Service
Customizing Error Handling for UpdatePanel Controls
Animating UpdatePanel Controls
Canceling an Asynchronous Postback
Giving Precedence to a Specific Asynchronous Postback
Working with PageRequestManager Events
The UpdateProgress Control
Introduction to the UpdateProgress Control
Programming UpdateProgress Controls in Client Script
The Timer Control
Introduction to the Timer Control
Using the Timer Control with Multiple UpdatePanel Controls
ASP.NET Application Services
Using Forms Authentication
Using Profile Information
Web Services
Exposing Web Services to Client Script
Calling Web Services from Client Script
ASP.NET AJAX Extensibility
Creating Custom ASP.NET AJAX Non-Visual Client Components
Creating Custom ASP.NET AJAX Client Controls
Creating an Extender Control
Adding Client Capabilities to a Web Server Control
Creating a Client Component Class Using the Prototype Model
Defining Custom Component Properties and Raising PropertyChanged Events
Releasing Component Resources

Using the UpdatePanel Control with a Web Service

Introduction

The UpdatePanel control simplifies partial-page rendering in ASP.NET Web pages because Microsoft ASP.NET 2.0 AJAX Extensions manages the asynchronous postback request and manages updating the page. ASP.NET 2.0 AJAX Extensions also enables you to call ASP.NET Web services by using ECMAScript (JavaScript) in the browser. One of the advantages of calling a Web service by using client script is that waiting for the response from a Web service request does not block the browser. Users can continue to work without waiting for the Web service to finish processing the request.

This tutorial shows how to use a Web service by using an UpdatePanel control. A JavaScript function calls the Web service to retrieve data, and then to populate DOM elements inside an UpdatePanel control with data returned from the Web service. Server code preserves the retrieved Web service data between asynchronous postbacks.

This topic assumes that you are familiar with the UpdatePanel control and with Web services. If you are not, review the following topics:

You can see the code in action in this tutorial by clicking the Run It buttons. To implement the procedures in your own development environment you need:

  • Microsoft Visual Studio 2005 or Visual Web Developer Express Edition.

  • The latest release of Microsoft ASP.NET AJAX installed and configured. For more information, see Installing ASP.NET AJAX.

  • An ASP.NET AJAX Web site.

  • Access to the Northwind database and a connection string named NorthwindConnectionString defined in the Web.config file. For information about how to create a connection string, see How to: Read Connection Strings from the Web.config File.

Creating a Web Service

To begin, you will create a Web service that you can call.

To create a Web service to return product quantities

  1. In an AJAX-enabled ASP.NET Web site, create a new Web service file named ProductQueryService.asmx.

    For information about how to create a Web service, see Calling Web Services from Client Script.

  2. In the Web service code, import the N:System.Data, N:System.Data.SqlClient, System.Configuration, and N:System.Web.Script.Services namespaces.

    CS

    using System.Web.Script.Services;
    using System.Data;
    using System.Data.SqlClient;
    using System.Configuration;
    
    

    VB

    Imports System.Data
    Imports System.Data.SqlClient
    Imports System.Configuration
    Imports System.Web.Script.Services
    
    

    Types from these namespaces will be used in the Web service method that you will create.

  3. Put the ProductQueryService class inside a namespace called Samples.

  4. Add the ScriptServiceAttribute attribute to the class.

    This attribute enables the Web service to be invoked from client script.

  5. Replace the default HelloWorld method with the following GetProductQuantity method:

    CS

    [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;
    }
    
    

    VB

    <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
    
    

    The code performs the following tasks:

    • Creates a new SqlConnection object that uses a connection string named NorthwindConnectionString.

    • Creates a new SqlCommand object that contains a SQL command to retrieve the number of units in stock for a specified product ID.

    • Sets the return value to a string that is used as the response that is sent to the browser.

      note

      For this tutorial, the Web method introduces an artificial delay. In practice, you would not introduce a delay. Instead, any delay would be the result of server traffic or of Web service code that takes a long time to process, such as a long-running database query.

  6. Save your changes, and then press CTRL+F5 to view the page in a browser.

  7. Click the GetProductQuantity link to invoke the Web method.

  8. Enter 6 in the productID box and then click Invoke.

    The quantity of the product is returned as XML in the browser. This demonstrates that the Web service is functioning as intended.

Creating JavaScript Code to Call the Web Service

In this procedure you will create a JavaScript file that calls the Web service that you created in the previous procedure.

To create a JavaScript file to use the Web Service

  1. Create a new JScript file named ProductQueryScript.js.

  2. Add the following script to the file:

    CS

    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;
       }
    }
    
    

    VB

    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;
       }
    }
    
    

    The script performs the following tasks:

    • Creates a function named GetQuantity that invokes the GetProductQuantity Web service method.

    • Creates a function named OnSucceeded that is invoked when the Web service call returns with a result.

Creating a Web Page to Display Data

Next, you will create a Web page that contains an UpdatePanel control. Controls inside the UpdatePanel control display product information from the Northwind database.

To create a Web page to display products

  1. Create a new Web page and switch to Design view.

  2. In the AJAX Extensions tab of the toolbox, double-click the ScriptManager control to add it to the page.

  3. Double-click the UpdatePanel control in the toolbox to add an UpdatePanel control to the page.

    UpdatePanel Tutorial
  4. Click inside the UpdatePanel control, and then in the Data tab of the toolbox, double-click the DataList control.

  5. In the DataList Tasks panel, from the Choose Data Source list, select <New data source…>.

    note

    If you do not see the DataList Tasks panel, right-click the DataList control and select Show Smart Tag.

    The Data Source Configuration wizard is displayed.

  6. Select Database, accept the default name SqlDataSource1, and then click OK.

  7. In the Which data connection should your application use to connect to the database list, select NorthwindConnectionString, and then click Next.

  8. Under How would you like to retrieve data from your database, select Specify columns from a table or view, select Products from the list, and in the Columns list, select ProductID and ProductName.

  9. Click the WHERE button.

    The Add WHERE Clause dialog box is displayed.

  10. In the Columns list, select CategoryID and in the Source list, select None.

  11. In the Parameter properties section of the dialog box, in the Value text box, enter 1.

  12. Click Add to add the WHERE clause to the SQL statement.

  13. Click OK to close the Add WHERE Clause dialog box.

    UpdatePanel Tutorial
  14. Click Next and then click Finish to close the wizard.

  15. Switch to Source view and confirm that the SqlDataSource control resembles the following example:

    CS

    <asp:SqlDataSource ID="SqlDataSource1" runat="server" 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>
    
    

    VB

    <asp:SqlDataSource ID="SqlDataSource1" runat="server" 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. Switch to Design view.

  17. Select the DataList control, and in the DataList Tasks panel, click Edit Templates.

  18. Add two Button controls to the UpdatePanel control outside the DataList control.

  19. .Set the first button's ID property to Category1Button and its Text property to Category 1. Set the second button's ID property to Category2Button and its Text property to Category 2.

    UpdatePanel Tutorial
  20. Select the UpdatePanel control, and in the Properties window, set the UpdateMode property to Conditional and set the ChildrenAsTriggers property to false.

  21. In the Triggers box, click the ellipsis (…) button and in the UpdatePanel Trigger Collection Editor dialog box, add each category button as an asynchronous postback trigger.

    UpdatePanel Tutorial
  22. Set the Click event handler for the first button to Category1Button_Click and set the Click event handler for the second button to Category2Button_Click.

  23. Switch to Source view and create the following event handlers for the two buttons:

    CS

    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";
    }
    
    

    VB

    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
    
    

    The event handler code sets the CategoryID parameter of the SelectParameters collection in the SqlDataSource control, based on which button was pressed. This enables users to toggle between two categories.

  24. Save your changes and press CTRL+F5 to view the page in a browser.

  25. Click Category 2 and verify that the page displays new information but does not refresh the whole page.

    note

    Do not close the page.

Calling a Web Service to Retrieve the Data

You will now call the Web service by using the JavaScript file that you created earlier. The JavaScript code uses the returned data to populate DOM elements inside the UpdatePanel control. Server code in the page preserves data that is populated from the Web service and adds the data to the page's view state. This retains the data in any subsequent asynchronous postbacks.

To use a Web Service to return product quantities

  1. In the page, switch to Design view.

  2. Select the DataList control and in the DataList Tasks panel, select Edit Templates.

  3. Add a TextBox and a Button control to the item template.

    Add the new controls underneath the existing text and labels in the template.

  4. Select the button and in the Properties window, set its Text property to Get Quantity from Web Service.

    The item template of the DataList control should resemble the following figure.

    UpdatePanel Tutorial
  5. Select the DataList control, and then in the Events tab of the Properties window, double-click the ItemDataBound event.

  6. Add the following code:

    CS

    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();
        }        
    }
    
    

    VB

    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
    
    

    The code sets properties for controls in each DataListItem object as follows:

    • The OnClientClick property of the button calls a JavaScript function that in turn calls the Web service.

    • The value of the text box is set if a tracking property named ProductInfo contains a key for the product ID. The ProductInfo property is defined in the next step of this procedure.

  7. Add a property named ProductInfo to the page.

    CS

    protected SortedList ProductInfo
    {
        get { return (SortedList)(ViewState["ProductInfo"] ?? new SortedList()); }
        set { ViewState["ProductInfo"] = value; }
    }
    
    

    VB

    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
    
    

    This property is a SortedList object that tracks data that has been added to the page from the Web service. The first time that the page is rendered, the list is empty. During subsequent asynchronous postbacks, items might be added to the list.

  8. Add the following Page_Load event handler:

    CS

    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;
        }
    }
    
    

    VB

    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
    
    

    The code checks whether the request is an asynchronous postback. If it is, any data items that are added by the Web service are added to the ProductInfo property. This enables them to be tracked in view state and displayed in the UpdatePanel during subsequent partial-page updates. If the data items are not tracked in view state, they are not retained in subsequent asynchronous postbacks.

  9. Switch to Design view.

  10. Select the ScriptManager control.

  11. In the Properties window, select the Services property and click the ellipsis (…) button to display the ServiceReference Collection Editor dialog box.

  12. Click Add to add a service reference.

  13. Set the Path property of the service reference to ProductQueryService.asmx, which is the Web service that you created previously.

    Adding a service reference causes the ScriptManager control to generate client proxy classes so that the Web service can be called by using JavaScript.

    UpdatePanel Tutorial
  14. Click OK to close the ServiceReference Collection Editor dialog box.

  15. Select the ScriptManager control, and then in the Properties window, select the Scripts property and click the ellipsis (…) button to display the ScriptReference Collection Editor dialog box.

  16. Click Add to add a script reference.

  17. Set the Path property of the script reference to ProductQueryScript.js, which is the JavaScript file that you created previously.

    Adding a script reference causes the ScriptManager control to insert the script after the has loaded.

    UpdatePanel Tutorial
  18. Click OK to close the ScriptReference Collection Editor dialog box.

  19. Save your changes and press CTRL+F5 to view the page in a browser.

    The page shows the products from the Northwind database whose category ID is 1. The text boxes next to each product are empty because no Web service calls have been made.

Verifying that Data is Persisted During Asynchronous Postbacks

You can now see how data from the Web service is persisted during asynchronous postbacks.

To verify that Web service data is persisted during asynchronous postbacks

  1. If the page is not already running, press CTRL+F5 to run the page.

  2. Click the Get Quantity from Web Service button for any product in the list and then wait for the value to be displayed in the text box.

  3. Click the Category 2 button.

  4. Click the Category 1 button.

    Notice that the value that was returned earlier by the Web service still appears, even after the asynchronous postbacks.

Review

This tutorial showed an example of using an UpdatePanel control with a Web service that is called from JavaScript code in the browser. The Web service returns data that is displayed inside the UpdatePanel control.

The result of calling the Web service from client script and of populating DOM elements by using the returned data is the same with or without UpdatePanel controls. When a page performs a postback or when an asynchronous postback occurs, the data that was previously displayed by using client script is lost. To avoid this problem, you can use server code to persist the data by making it part of view state. This enables you to maintain the data during subsequent postbacks. If the data from the Web service is displayed in DOM elements outside UpdatePanel controls and you do not want to persist the data during asynchronous postbacks, you do not have to provide server code to maintain it.

Because the button that triggered the Web service call is inside the UpdatePanel control, the ChildrenAsTriggers property is set to false. Other postback controls inside the panel are defined as triggers for the panel.