Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 57 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
57
Dung lượng
1,2 MB
Nội dung
24 CHAPTER 1 Introducing ASP.NET AJAX For the employee lookup logic, create a simple class called HumanResources.cs , and copy the code in listing 1.7. using System; public static class HumanResources { public static int GetEmployeeCount(string department) { int count = 0; switch (department) { case "Sales": count = 10; break; case "Engineering": count = 28; break; case "Marketing": Listing 1.7 A simple class that returns the number of employees in a department Figure 1.10 The ASP.NET AJAX-Enabled Web Site template creates a website that references the ASP.NET AJAX assembly and configures the web.config file for Ajax integration. ASP.NET AJAX in action 25 count = 44; break; case "HR": count = 7; break; default: break; } return count; } } The HumanResources class contains one method, GetEmployeeCount , which takes the department name as a parameter. It uses a simple switch statement to retrieve the number of employees in the department. (To keeps things simple, we hard- coded the department names and values.) When you created the new website, a default page named Default.aspx was also generated. Listing 1.8 shows the initial version of the page. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <div> </div> </form> </body> </html> What’s different in this page from the usual default page created by Visual Studio is the addition of the ScriptManager control. We briefly defined the ScriptMan- ager earlier in the chapter as the brains of an Ajax-enabled page. In this example, all you need to know about the ScriptManager is that it’s required to Ajax-enable a Listing 1.8 Default page created by the ASP.NET AJAX-Enabled Web Site template ScriptManager control 26 CHAPTER 1 Introducing ASP.NET AJAX page—it’s responsible for delivering the client-side scripts to the browser and managing the partial updates on the page. If these concepts still sound foreign, don’t worry; they will make more sense once you start applying them. As it turns out, creating the application requested by HR is fairly trivial. List- ing 1.9 shows the markup portion of the solution. <div> <asp:ListBox AutoPostBack="true" runat="server" ID="Departments" OnSelectedIndexChanged="Departments_SelectedIndexChanged"> <asp:ListItem Text="Engineering" Value="Engineering" /> <asp:ListItem Text="Human Resources" Value="HR" /> <asp:ListItem Text="Sales" Value="Sales" /> <asp:ListItem Text="Marketing" Value="Marketing" /> </asp:ListBox> </div> <br /> <div> <asp:Label ID="EmployeeResults" runat="server" /> </div> A ListBox is used to display the catalog of departments to choose from. The Auto- PostBack property of the control is initialized to B true so that any selection made invokes a postback on the form. This action fires the SelectedIndexChanged event and calls the C Departments_SelectedIndexChanged handler in the code. At the bottom of the page is a Label control where D the results are displayed. To com- plete the application, you implement the UI logic that looks up the employee count for the selected department in the code-behind file (see listing 1.10). protected void Departments_SelectedIndexChanged(object sender, EventArgs e) { EmployeeResults.Text = string.Format("Employee count: {0}", HumanResources.GetEmployeeCount(Departments.SelectedValue)); } When the application is launched and one of the departments is selected, it should look like figure 1.11. Listing 1.9 Setting AutoPostBack to true causes a postback and invokes the server- side code. Listing 1.10 Retrieve the employee count and update the UI when a new department has been selected. Invoke postbacks on each update B Register handler C Label for results D ASP.NET AJAX in action 27 The program works as expected: Selecting a department retrieves the number of employees and displays the results at the bottom of the page. The only issue is that the page refreshes each time a new department is chosen. Handling this is also triv- ial; you wrap the contents of the form in an UpdatePanel control (see listing 1.11). <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <div> <asp:ListBox AutoPostBack="true" runat="server" ID="Departments" OnSelectedIndexChanged="Departments_SelectedIndexChanged"> <asp:ListItem Text="Engineering" Value="Engineering" /> <asp:ListItem Text="Human Resources" Value="HR" /> <asp:ListItem Text="Sales" Value="Sales" /> <asp:ListItem Text="Marketing" Value="Marketing" /> </asp:ListBox> </div> <br /> <div> <asp:Label ID="EmployeeResults" runat="server" /> </div> </ContentTemplate> </asp:UpdatePanel> Listing 1.11 UpdatePanel control, designating page regions that can be updated dynamically Figure 1.11 The employee-lookup application before adding any Ajax support Content that can be updated dynamically 28 CHAPTER 1 Introducing ASP.NET AJAX As an alternative, figure 1.12 shows what the solution looks like from the Design view in Visual Studio. By default, content placed in the ContentTemplate tag of the UpdatePanel control is updated dynamically when an asynchronous postback occurs. This addi- tion to the form suppresses the normal postback that most ASP.NET developers are accustomed to and sends back to the server an asynchronous request that delivers to the browser the new UI for the form to render. What do we mean when we say asynchronous postback? Most ASP.NET developers are familiar with only one kind of postback. With the UpdatePanel, the page still goes through its normal lifecycle, but the postback is marked as being asynchro- nous with some creative techniques that we’ll unveil in chapter 7. As a result, the page is handled differently during the lifecycle so that updates can be made incre- mentally rather than by refreshing the entire page. For now, you can see that add- ing this type of functionality is simple and transparent to the logic and development of the page. The next time you run the page and select a department, the UI updates dynamically without a full page refresh. In summary, by adding a few new server controls on the page you’ve essentially eliminated the page from reloading itself and taking away any interaction from the user. 1.3.2 UpdateProgress control You show the application to the director of human resources, who is impressed. However, he notices that when he goes home and tries the application again, with a slow dial-up connection, it takes significantly longer for the page to display the Figure 1.12 Using the Design view in Visual Studio provides a visual alternative to editing the layout and elements on the page. ASP.NET AJAX in action 29 results. The delay in response time confuses the director and initially makes him wonder if something is wrong with the application. Before the introduction of Ajax, a page being refreshed was an indication to most users that something was being processed or that their actions were accepted. Now, with the suppression of the normal postback, users have no indica- tion that something is happening in the background until it’s complete. They need some sort of visual feedback notifying them that work is in progress. The UpdateProgress control offers a solution to this problem. Its purpose is to provide a visual cue to the user when an asynchronous postback is occurring. To please the HR director, you add the following snippet of code to the end of the page: <asp:UpdateProgress ID="UpdateProgress1" runat="server"> <ProgressTemplate> <img src="images/indicator.gif" /> Loading </ProgressTemplate> </asp:UpdateProgress> When you run the application again, the visual cue appears when the user selects a new department (see figure 1.13). If you’re running this application on your local machine, chances are that the page updates fairly quickly and you may not get to see the UpdateProgress control working. To slow the process and see the loading indicator, add to the code the Sleep command shown in listing 1.12. Figure 1.13 It’s generally a good practice to inform users that work is in progress during an asynchronous update. 30 CHAPTER 1 Introducing ASP.NET AJAX protected void Departments_SelectedIndexChanged(object sender, EventArgs e) { EmployeeResults.Text = string.Format("Employee count: {0}", HumanResources.GetEmployeeCount(Departments.SelectedValue)); System.Threading.Thread.Sleep(2000); } WARNING Don’t call the Sleep method in production code. You use it here only for demonstration purposes so you can see that the UpdateProgress control is working. When used effectively with the UpdatePanel, the UpdateProgress control is a handy tool for relaying visual feedback to the user during asynchronous opera- tions. We discuss best practices throughout the book; in this case, providing visual feedback to the user is strongly encouraged. 1.3.3 Simple client-centric example The server-centric approach is appealing because of its simplicity and transparency, but it has drawbacks as well. Ajax development is more effective and natural when the majority of the application is running from the browser instead of on the server. One of the main principles of an Ajax application is that the browser is supposed to be delivered a smarter application from the server, thus limiting the server’s role to providing only the data required to update the UI. This approach greatly reduces the amount of data sent back and forth between the browser and server. To get started with the client-centric approach, let’s add a new web service called HRService.asmx. For clarity, deselect the Place Code in Separate File option in the Add New Item dialog, and then add the service. TIP A common best practice would be to define an interface first (contract first) and to keep the logic in a separate file from the page. However, this exam- ple keeps things simple so we can remain focused on the Ajax material. Next, paste the code from listing 1.13 into the web service implementation to add support for looking up the employee count. Listing 1.12 Adding a Sleep command to test the UpdateProgress control. Testing only ASP.NET AJAX in action 31 using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.Web.Script.Services; [ScriptService] [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class HRService : System.Web.Services.WebService { [ScriptMethod] [WebMethod] public int GetEmployeeCount(string department) { return HumanResources.GetEmployeeCount(department); } } First, note the B using statement for the System.Web.Script.Services name- space. This namespace is part of the core ASP.NET AJAX framework that encapsu- lates some of the network communication and scripting functionality. It’s not required, but it’s included to save you a little extra typing. Next are the new attributes adorned on the C class and D method declarations of the web service. These attributes are parsed by the ASP.NET AJAX framework and used to deter- mine what portions of the service are exposed in the JavaScript proxies. The ScriptMethod attribute isn’t required, but you can use it to manipulate some of a method’s settings. If you view the ASMX file in your browser but append /js to the end of the URL, you get a glimpse of the JavaScript proxy that is generated for this service. Figure 1.14 shows the generated JavaScript proxy that is produced by the frame- work after decorating the class and methods in the web service. In chapter 5, we’ll spend more time explaining what the proxy generates. In the meantime, if you glance at the proxy, you’ll notice at the end the matching call to the service method GetEmployeeCount . This gives the client-side script a mechanism for calling the web methods in the service. The call takes a few extra parameters that you didn’t define in the service. With a web service ready to go, you can create a new page for this solution. Start by adding a new web form to the site, called EmployeeLookupClient.aspx. The first requirement in adding Ajax support to the page is to include the Script- Manager control. This time, you’ll also declare a service reference to the local web Listing 1.13 Adding attributes to the class and methods Namespace for script services B Declare service for scripting support C Declare method for scripting support D 32 CHAPTER 1 Introducing ASP.NET AJAX service, to generate the JavaScript proxies for the service that you can now call from in the client-side script (see listing 1.14). <asp:ScriptManager ID="ScriptManager1" runat="server"> <Services> <asp:ServiceReference Path="HRService.asmx" /> </Services> </asp:ScriptManager> To complete the declarative portion of the solution, copy the code shown in list- ing 1.15. Listing 1.14 Adding a service reference, which will generate the JavaScript proxies Figure 1.14 The framework generates a JavaScript proxy so calls to a web service can be made from the client-side script. Reference for JavaScript proxies ASP.NET AJAX in action 33 <div> <select id="Departments" size="5"> <option value="Engineering">Engineering</option> <option value="HR">Human Resources</option> <option value="Sales">Sales</option> <option value="Marketing">Marketing</option> </select> </div> <br /> <div> <span id="employeeResults"></span> <span id="loading" style="display:none;"> <img src="images/indicator.gif" alt="" /> Loading </span> </div> Because you aren’t relying on any of the business or UI logic to come from the server, you can use normal HTML elements on the page instead of the heavier server con- trols. This includes a select element for the list of B departments and a C span element to display visual feedback to the user when retrieving data from the server. To make this page come to life, add the JavaScript shown in listing 1.16. <script type="text/javascript"> <! var departments = null; Sys.Application.add_load(page_load); Sys.Application.add_unload(page_unload); function page_load(sender, e){ departments = $get("Departments"); $addHandler(departments, "change", departments_onchange); } function page_unload(sender, e){ $removeHandler(departments, "change", departments_onchange); } function departments_onchange(sender, e){ $get("employeeResults").innerHTML = ""; $get("loading").style.display = "block"; Listing 1.15 Markup portion of the client-centric solution Listing 1.16 The script portion of the employee lookup application List of departments B Visual feedback during data retrieval C Register load and unload events B Register change event C Release change event D [...]... detect the init stage, you have to do a little more work Declaring a pageInit function won’t have any effect Instead, you have to write an additional statement with a call to the add_init method of Sys.Application, as shown in listing 2. 2 Listing 2. 2 Handling the init event of Sys.Application Sys.Application.add_init(pageInit); function pageInit() { alert("Entered the Init stage!"); } The add_init method... exploring the library The first step is learning how to load the library’s script files in a web page 2. 1 .2 Ajax- enabling an ASP.NET page The Microsoft Ajax Library is organized in client classes contained in namespaces The root namespace is called Sys The other namespaces are children of the root namespace Table 2. 1 lists the namespaces defined in the library and the type of classes that they contain... Determines whether the start of the String object matches the specified string trim Removes leading and trailing white space from a String object instance trimEnd Removes trailing white space from a String object instance trimStart Removes leading white space from a String object instance An object familiar to NET developers is the string builder A string builder is an object that speeds up string concatenations... Default.aspx page and insert the code from listing 2. 1 in the page’s form tag 46 CHAPTER 2 First steps with the Microsoft Ajax Library Listing 2. 1 Code for testing the client-page lifecycle The code in listing 2. 1 is simple enough... Application object introduced in the previous section In the following section, we’ll explain how the Application object and client components interact during the client-page lifecycle 44 CHAPTER 2 First steps with the Microsoft Ajax Library Component Methods Events Logic Figure 2. 2 A component encapsulates some logic and exposes it through properties, methods and events Properties 2. 2 .2 Client-page lifecycle... hooking up the events raised by the window object and, in turn, firing its own events Client components are created during the init stage and disposed automatically in the unload stage The Application model 45 When the browser starts loading a web page, the DOM’s window object fires the load event This event is intercepted by the Application object, which, in turn, starts initializing the Microsoft Ajax. .. the code in pageLoad is executed as soon as the load stage is entered Figure 2. 4 shows the example up and running in Internet Explorer To see what happens during the unload stage, you can either press the F5 key or navigate away from the page Figure 2. 4 The “Hello Microsoft Ajax! ” program running in Internet Explorer The Application model 47 The pageLoad function When you’re using the Microsoft Ajax Library,... library 2. 1.1 Library features The Microsoft Ajax Library is rich in features, which we’ve grouped into logical categories Because we can’t explore all of them in a single chapter, the following list shows how the features are distributed in the book’s various chapters: ■ Application model—When you enable the Microsoft Ajax Library in a web page, an Application object is created at runtime In section 2. 2,... how the Microsoft Ajax Library participates in the partial-rendering mechanism Some of the features in the ASP.NET Futures package are interesting, and we decided to cover them in this book Chapter 11 is dedicated to XML Script, a declarative language—similar to the ASP.NET markup language—used to create JavaScript objects without writing a single line of JavaScript code Chapter 12 talks about how... the menu Instead, you only have to configure the menu and instantiate it in the page If you also need the same menu in a different page, you perform similar steps to include and initialize it The point is, the code should be packaged into a single, configurable object that can be reused in another application The primary tenet behind components is code reusability Components implement a well-defined set . count. Listing 1. 12 Adding a Sleep command to test the UpdateProgress control. Testing only ASP. NET AJAX in action 31 using System; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using. page. ASP. NET AJAX in action 29 results. The delay in response time confuses the director and initially makes him wonder if something is wrong with the application. Before the introduction of Ajax, . Ajax- enable a Listing 1.8 Default page created by the ASP. NET AJAX- Enabled Web Site template ScriptManager control 26 CHAPTER 1 Introducing ASP. NET AJAX page—it’s responsible for delivering the client-side