ASP.NET AJAX Programmer’s Reference - Chapter 15 ppt

62 270 0
ASP.NET AJAX Programmer’s Reference - Chapter 15 ppt

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Proxy Classes The previous chapter provided you with in-depth coverage of the ASP.NET AJAX REST method call request processing infrastructure. This chapter shows you how this infrastructure hides its complexity behind proxy classes to enable you to program against a remote object as you would against a local object. What’s a Proxy, Anyway? Let’s revisit the add JavaScript function shown in Listing 14-14 of Chapter 14 , and shown again here in Listing 15-1 . This JavaScript function was registered as the event handler for the Add but- ton’s click event of in Listing 14-14 . Listing 15-1: The add Method function add() { var servicePath = “ http://localhost/AJAXEnabledFuturesWebSite2/Math.asmx”; var methodName = “Add”; var useGet = false; var xValue = $get(“firstNumber”).value; var yValue = $get(“secondNumber”).value; var params = {x : xValue, y : yValue}; var userContext = $get(“result”); var webServiceProxy = new Sys.Net.WebServiceProxy(); webServiceProxy.set_timeout(0); request = webServiceProxy._invoke(servicePath, methodName, useGet, params, onSuccess, onFailure, userContext); } Now here is a question for you: How would you code this add method if the Math class (see Listing 14-15 ) were a local class in your client-side code, such as the local class shown in Listing 15-2 ? c15.indd 597c15.indd 597 8/20/07 9:08:00 PM8/20/07 9:08:00 PM Chapter 15: Proxy Classes 598 Listing 15-2: A Local Class with the Same Name and Methods as the Remote Web Service Type.registerNamespace(“MyNamespace”); MyNamespace.Math = function () { } MyNamespace.Math.prototype = { Add : function (x, y) { return x + y; } } MyNamespace.Math.registerClass(“MyNamespace.Math”); Wouldn’t your implementation of the add method be something like the one shown in Listing 15-3 ? Listing 15-3: Implementation of add Method if the Web Service Class Were a Local Class function add() { var math = new MyNamespace.Math(); var xValue = $get(“firstNumber”).value; var yValue = $get(“secondNumber”).value; var z = math.Add(Number.parseInvariant(xValue), Number.parseInvariant(yValue)); $get(“result”).innerText = z; } As you can see in this listing, if the Math object were a local object, you would directly invoke the Add method on the object and directly pass the x and y values into the Add method itself. However, when the Math object becomes a Web service, it is a remote object, so you cannot directly invoke the Add method on it, nor can you directly pass the x and y values into it. When you’re calling the Add method on the remote Math object: ❑ You have to worry about the service path where the remote Math object is located: var servicePath = “http://localhost/AJAXEnabledFuturesWebSite2/Math.asmx”; You don’t have to worry about the location of a local Math object, because it always resides in the same address space as the rest of your program and, consequently, you have direct access to the object. ❑ You have to pass the name of the method as a string into the _invoke method of the WebServiceProxy object: var methodName = “Add”; request = webServiceProxy._invoke(servicePath, methodName, useGet, params, onSuccess, onFailure, userContext); c15.indd 598c15.indd 598 8/20/07 9:08:01 PM8/20/07 9:08:01 PM Chapter 15: Proxy Classes 599 This is obviously very different from a local method invocation where you directly invoke the method on the object instead of passing a string around. ❑ You have to pass the names and values of the parameters of the method as a dictionary into the _invoke method of the WebServiceProxy object. var params = {x : xValue, y : yValue}; request = webServiceProxy._invoke(servicePath, methodName, useGet, params, onSuccess, onFailure, userContext); This is obviously very different from a local method invocation where you directly pass these parameters into the method itself instead of passing a dictionary around. ❑ You’re trying to call a method named Add , which takes two parameters of type double and returns a value of type double , on an object of type Math , but you have to call a method with a different name ( _invoke ), with completely different parameters ( servicePath , methodName , useGet , params , onSucess , onFailure , and userContext ), and with a completely different return type ( WebRequest ), on a completely different object (the WebServiceProxy object): request = webServiceProxy._invoke(servicePath, methodName, useGet, params, onSuccess, onFailure, userContext); This is obviously very different from a local method invocation where you directly invoke the Add method on the Math object. As you can see, invoking the Add method on the remote Math object doesn’t look anything like invoking the Add method on a local Math object. Proxy Class The ASP.NET AJAX framework provides you with a local object that has the following characteristics: ❑ It has the same name as the remote object. For example, in the case of the Math Web service, the AJAX framework provides you with a local object named Math . ❑ It exposes methods with the same names as the methods of the remote object. For example, the local Math object associated with the remote Math Web service object exposes a method named Add . ❑ Its methods take parameters with the same names as the associated methods of the remote object. For example, the Add method of the local Math object associated with the remote Math Web service object also takes two parameters with the same names as the parameters of the Add method of the remote Math Web service object: x and y . ❑ Its methods take parameters of the same types as the associated methods of the remote object. For example, the Add method of the local Math object associated with the remote Math Web ser- vice object also takes two parameters of the same types as the parameters of the Add method of the remote Math Web service object: double . ❑ Its methods return values of the same types as the associated methods of the remote object. For example, the Add method of the local Math object associated with the remote Math Web service object returns a value of the same type as the return value of the Add method of the remote Math Web service object: double . c15.indd 599c15.indd 599 8/20/07 9:08:01 PM8/20/07 9:08:01 PM Chapter 15: Proxy Classes 600 This enables you to program against the local object, instead of the WebServiceProxy object as you did in the last chapter, and consequently, makes programming against remote objects more like programming against local objects. Because this local object makes it feel like you’re directly interacting with the remote object, it is known as a proxy object . In other words, this local object acts as a proxy for the remote object. Let’s begin by discussing the implementation of the proxy class and object that the ASP.NET AJAX framework automatically generates for you. (The mechanism that actually generates this proxy class and object is discussed later in the chapter.) As you learned in the previous chapter, there are three types of remote method invocations: ❑ Invoking a Web method that is part of a Web service ❑ Invoking a page method that is part of an ASP.NET page ❑ Invoking a method that is part of a custom class Therefore, there are three types of proxy classes: ❑ Proxy classes associated with Web services ❑ Proxy classes associated with page methods ❑ Proxy classes associated with custom classes Proxy Classes Associated with Web Services Listing 15-4 presents the implementation of the local Math proxy class associated with the remote Math Web service class. Listing 15-4: The Local Math Proxy Class Associated with the Remote Math Web Service Class Type.registerNamespace(‘MyNamespace’); MyNamespace.Math = function() { MyNamespace.Math.initializeBase(this); this._timeout = 0; this._userContext = null; this._succeeded = null; this._failed = null; } MyNamespace.Math.prototype = { Add : function(x, y, succeededCallback, failedCallback, userContext) { var servicePath = MyNamespace.Math.get_path(); var methodName = ‘Add’; var useGet = false; var params = {x : x, y : y}; var onSuccess = succeededCallback; c15.indd 600c15.indd 600 8/20/07 9:08:01 PM8/20/07 9:08:01 PM Chapter 15: Proxy Classes 601 var onFailure = failedCallback; return this._invoke(servicePath, methodName, useGet, params, onSuccess,onFailure, userContext); } } MyNamespace.Math.registerClass(‘MyNamespace.Math’, Sys.Net.WebServiceProxy); MyNamespace.Math._staticInstance = new MyNamespace.Math(); MyNamespace.Math.set_path = function(value) { MyNamespace.Math._staticInstance._path = value; } MyNamespace.Math.get_path = function() { return MyNamespace.Math._staticInstance._path; } MyNamespace.Math.set_timeout = function(value) { MyNamespace.Math._staticInstance._timeout = value; } MyNamespace.Math.get_timeout = function() { return MyNamespace.Math._staticInstance._timeout; } MyNamespace.Math.set_defaultUserContext = function(value) { MyNamespace.Math._staticInstance._userContext = value; } MyNamespace.Math.get_defaultUserContext = function() { return MyNamespace.Math._staticInstance._userContext; } MyNamespace.Math.set_defaultSucceededCallback = function(value) { MyNamespace.Math._staticInstance._succeeded = value; } MyNamespace.Math.get_defaultSucceededCallback = function() { return MyNamespace.Math._staticInstance._succeeded; } MyNamespace.Math.set_defaultFailedCallback = function(value) { MyNamespace.Math._staticInstance._failed = value; } (continued) c15.indd 601c15.indd 601 8/20/07 9:08:02 PM8/20/07 9:08:02 PM Chapter 15: Proxy Classes 602 Listing 15-4 (continued ) MyNamespace.Math.get_defaultFailedCallback = function() { return MyNamespace.Math._staticInstance._failed; } MyNamespace.Math.set_path(“/AJAXFuturesEnabledWebSite2/Math.asmx”); MyNamespace.Math.Add = function(x, y, onSuccess, onFailed, userContext) { MyNamespace.Math._staticInstance.Add(x, y, onSuccess, onFailed, userContext); } This code listing defines a namespace with the same name as the namespace of the remote Math Web service class: Type.registerNamespace(‘MyNamespace’); The local Math proxy class derives from the WebServiceProxy class: MyNamespace.Math.registerClass(‘MyNamespace.Math’, Sys.Net.WebServiceProxy); All ASP.NET AJAX proxy classes directly or indirectly derive from the Sys.Net.WebServiceProxy class. As you can see from in the following excerpt from Listing 15-4 , this local Math proxy class exposes a method with the same name as the remote Web service class — Add . This method takes parameters with the same names and types as the remote Web service class’s Add method parameters, and returns a value of the same type as the remote Web service class’s Add method return value: MyNamespace.Math.prototype = { Add : function(x, y, succeededCallback, failedCallback, userContext) { var servicePath = MyNamespace.Math.get_path(); var methodName = ‘Add’; var useGet = false; var params = {x : x, y : y}; var onSuccess = succeededCallback; var onFailure = failedCallback; return this._invoke(servicePath, methodName, useGet, params, onSuccess,onFailure, userContext); } } The Add method of this local Math proxy class encapsulates the code that you would otherwise have to write to interact with the WebServiceProxy object as you did in the previous chapter. Note that Listing 15-4 instantiates an instance of this local Math proxy class and assigns the instance to a private static field on this class named _staticInstance : MyNamespace.Math._staticInstance = new MyNamespace.Math(); c15.indd 602c15.indd 602 8/20/07 9:08:02 PM8/20/07 9:08:02 PM Chapter 15: Proxy Classes 603 The code then defines static getters and setters that delegate to the associated getters and setters of this static Math proxy instance. Also note that the code exposes a static method named Add on this local Math proxy class, which delegates to the Add method of the static Math proxy instance: MyNamespace.Math.Add = function(x, y, onSuccess, onFailed, userContext) { MyNamespace.Math._staticInstance.Add(x, y, onSuccess, onFailed, userContext); } Finally, the code invokes the set_path static method on this local Math proxy class to set the service path for the static Math proxy instance: MyNamespace.Math.set_path(“/AJAXFuturesEnabledWebSite2/Math.asmx”); Listing 15-5 presents a page that uses the Math proxy class. As you’ll see later in this chapter, the ASP.NET AJAX framework automatically generates the code for the proxy class such as the Math proxy class shown in this listing. For now, assume that you generated this code yourself and treat it like any other client code. As such, the content of Listing 15-4 is stored in a JavaScript file named MathWebServiceProxy.js , and Listing 15-5 adds a reference to this JavaScript file. Now let’s walk through the implementation of the add JavaScript function shown in the following excerpt from Listing 15-5 : function add() { var userContext = $get(“result”); var xValue = $get(“firstNumber”).value; var yValue = $get(“secondNumber”).value; MyNamespace.Math.Add(xValue, yValue, onSuccess, onFailure, userContext); } Thanks to the Math proxy class, you get to directly invoke the Add method and directly pass the x and y values into this method. Note that there is no sign of the WebServiceProxy and its weird-looking _invoke method. The Math proxy class enables you to program against the remote Math Web service object as if you were programming against a local Math object. In other words, the Math proxy class gives your client code the illusion that it is making a local method call. Listing 15-5: A Page that Uses the Local Static Math Proxy Instance <%@ Page Language=”C#” %> <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml”> <head runat=”server”> <title>Untitled Page</title> <script type=”text/javascript” language=”javascript”> var request; function onSuccess(result, userContext, methodName) { (continued) c15.indd 603c15.indd 603 8/20/07 9:08:02 PM8/20/07 9:08:02 PM Chapter 15: Proxy Classes 604 Listing 15-5 (continued) userContext.innerHTML = “<b<>u>” + result + “</u></b>”; } function onFailure(result, userContext, methodName) { var builder = new Sys.StringBuilder(); builder.append(“timedOut: “); builder.append(result.get_timedOut()); builder.appendLine(); builder.appendLine(); builder.append(“message: “); builder.append(result.get_message()); builder.appendLine(); builder.appendLine(); builder.append(“stackTrace: “); builder.appendLine(); builder.append(result.get_stackTrace()); builder.appendLine(); builder.appendLine(); builder.append(“exceptionType: “); builder.append(result.get_exceptionType()); builder.appendLine(); builder.appendLine(); builder.append(“statusCode: “); builder.append(result.get_statusCode()); builder.appendLine(); builder.appendLine(); builder.append(“methodName: “); builder.append(methodName); alert(builder.toString()); } function add() { var userContext = $get(“result”); var xValue = $get(“firstNumber”).value; var yValue = $get(“secondNumber”).value; MyNamespace.Math.Add(xValue, yValue, onSuccess, onFailure, userContext); } </script> </head> <body> <form id=”form1” runat=”server”> <asp:ScriptManager runat=”server” ID=”ScriptManager1”> <Scripts> <asp:ScriptReference Path=”MathWebServiceProxy.js” /> </Scripts> </asp:ScriptManager> <table> <tr> <td style=”font-weight: bold” align=”right”> c15.indd 604c15.indd 604 8/20/07 9:08:02 PM8/20/07 9:08:02 PM Chapter 15: Proxy Classes 605 First Number: </td> <td align=”left”> <input type=”text” id=”firstNumber” /></td> </tr> <tr> <td style=”font-weight: bold” align=”right”> Second Number: </td> <td align=”left”> <input type=”text” id=”secondNumber” /></td> </tr> <tr> <td colspan=”2” align=”center”> <button onclick=”add()”> Add</button></td> </tr> <tr> <td style=”font-weight: bold” align=”right”> Result: </td> <td align=”left”> <span id=”result” /> </td> </tr> </table> </form> </body> </html> Proxy Classes Associated with Page Methods The following code presents a proxy class associated with a page method named Add , which belongs to the PageMethods.aspx page: PageMethods = function() { PageMethods.initializeBase(this); this._timeout = 0; this._userContext = null; this._succeeded = null; this._failed = null; } PageMethods.prototype = { Add : function(x, y, succeededCallback, failedCallback, userContext) { return this._invoke(PageMethods.get_path(), ‘Add’, false, {x:x, y:y}, succeededCallback, failedCallback, userContext); } } PageMethods.registerClass(‘PageMethods’, Sys.Net.WebServiceProxy); (continued) c15.indd 605c15.indd 605 8/20/07 9:08:03 PM8/20/07 9:08:03 PM Chapter 15: Proxy Classes 606 (continued) PageMethods._staticInstance = new PageMethods(); PageMethods.set_path = function(value) { PageMethods._staticInstance._path = value; } PageMethods.get_path = function() { return PageMethods._staticInstance._path; } PageMethods.set_timeout = function(value) { PageMethods._staticInstance._timeout = value; } PageMethods.get_timeout = function() { return PageMethods._staticInstance._timeout; } PageMethods.set_defaultUserContext = function(value) { PageMethods._staticInstance._userContext = value; } PageMethods.get_defaultUserContext = function() { return PageMethods._staticInstance._userContext; } PageMethods.set_defaultSucceededCallback = function(value) { PageMethods._staticInstance._succeeded = value; } PageMethods.get_defaultSucceededCallback = function() { return PageMethods._staticInstance._succeeded; } PageMethods.set_defaultFailedCallback = function(value) { PageMethods._staticInstance._failed = value; } PageMethods.get_defaultFailedCallback = function() { return PageMethods._staticInstance._failed; } PageMethods.set_path(“/AJAXFuturesEnabledWebSite2/PageMethods.aspx”); PageMethods.Add = function(x, y, onSuccess, onFailed, userContext) { PageMethods._staticInstance.Add(x, y, onSuccess, onFailed, userContext); }; c15.indd 606c15.indd 606 8/20/07 9:08:03 PM8/20/07 9:08:03 PM [...]... attribute on the to false, run the same page, and view the source from your browser, you’ll get Listing 1 5-8 614 c15.indd 614 8/20/07 9:08:05 PM Chapter 15: Proxy Classes Listing 1 5-8 : The Source of the Page Shown in Listing 1 5-6 with a ScriptMode Value of Debug Notice that the boldface portion of Listing 1 5-7 is replaced by the boldface portion of Listing 1 5-8 : 617 c15.indd 617 8/20/07 9:08:06 PM Chapter 15: Proxy Classes This script block sets the src to the value /AJAXFuturesEnabledWebSite2/Math.asmx/jsdebug... scripts, including the script that defines, instantiates, and initializes the PageMethods client class: ServiceReference Listing 1 5-1 4 presents the implementation of the replica ServiceReference class 627 c15.indd 627 8/20/07 9:08:09 PM Chapter 15: Proxy Classes Listing 1 5-1 4: The ServiceReference Class using using using using using using using using using using using using using using using using... the purposes of the current discussion, you can ignore the /jsdebug option 629 c15.indd 629 8/20/07 9:08:09 PM Chapter 15: Proxy Classes ClientProxyGenerator Listing 1 5-1 5 presents the implementation of the replica ClientProxyGenerator class The following sections discuss the methods and properties of this class Listing 1 5-1 5: The ClientProxyGenerator Class using using using using using using using using... serviceRef.Path = “/AJAXFuturesEnabledWebSite2/Math.asmx”; Finally, it adds the instance to the Services collection of the current ScriptManager server control: ScriptManager1.Services.Add(serviceRef); 620 c15.indd 620 8/20/07 9:08:07 PM Chapter 15: Proxy Classes Parent/Child Pages As previously discussed, to take advantage of the ASP.NET AJAX server-side framework automatic proxy-code generation, you... ScriptManager server control, can add its ServiceReference and ScriptReference objects to the Services and Scripts collections of the ScriptManagerProxy server control and rest assured that the ASP.NET AJAX framework will automatically add these ServiceReference and ScriptReference objects to the ScriptManager server control Because the ServiceReference and ScriptReference objects added to the Services and... style=”font-weight: bold” align=”right”> Result: Listing 1 5-1 1 presents a page that hosts the user control shown in Listing 1 5-1 0 As you can see, the host page contains the ScriptManager server control, and the child user control contains the ScriptManagerProxy server control Listing 1 5-1 1: A Page that Hosts the User Control shown in Listing 1 5-1 0... ServiceReference object to the Services collection of the current ScriptManager server control is all it takes to instruct the ASP.NET AJAX server-side framework to automatically generate a client script that defines, instantiates, and initializes the proxy class To help you understand how the ASP.NET AJAX server-side framework manages to do this, this section implements fully functional 623 c15.indd... ServiceReferenceCollection(); return this._services; } } Listing 1 5-1 3 presents the implementation of the replica ServiceReferenceCollection class Thanks to the NET 2.0 generics, implementing a new type-safe collection class is just a matter of deriving from a generic collection class such as Collection Listing 1 5-1 3: The ServiceReferenceCollection Class using System.Collections; using System.Collections.Generic; . Listing 1 4-1 5 ) were a local class in your client-side code, such as the local class shown in Listing 1 5-2 ? c15.indd 597c15.indd 597 8/20/07 9:08:00 PM8/20/07 9:08:00 PM Chapter 15: Proxy. you run Listing 1 5-6 and view the source from your browser, you’ll see Listing 1 5-7 . Listing 1 5-7 : The Source for the Page Shown in Listing 1 5-6 <!DOCTYPE html PUBLIC -/ /W3C//DTD XHTML. get Listing 1 5-8 . c15.indd 614c15.indd 614 8/20/07 9:08:05 PM8/20/07 9:08:05 PM Chapter 15: Proxy Classes 615 Listing 1 5-8 : The Source of the Page Shown in Listing 1 5-6 with a ScriptMode Value

Ngày đăng: 09/08/2014, 06:23

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan