Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 54 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
54
Dung lượng
335,38 KB
Nội dung
Client-Server Communications The ASP.NET AJAX client-server communication layer consists of several important types that are discussed in this chapter. These types emulate their ASP.NET/.NET counterparts, which enables you to use similar server-side network programming techniques in your client-side network programming. The types in the ASP.NET AJAX client-server communication layer belong to the following namespace: Type.registerNamespace(‘Sys.Net’); WebRequest The ASP.NET AJAX WebRequest client class represents a Web request that the client-side code makes to the server. The following sections discuss the important members of this class. Constructor As you can see in Listing 12-1 , the WebRequest constructor defines the following fields: ❑ _url : A string that contains the target URL for the request. ❑ _headers : A dictionary that contains the names and values of the request headers. ❑ _body : A string that contains the body of the request. ❑ _userContext : Contains a JavaScript object that provides application-specific contextual information. ❑ _httpVerb : A string that contains the HTTP verb being used to make the request. ❑ _executor : A field of type WebRequestExecutor that references the WebRequestExecutor object responsible for executing the request. The WebRequestExecutor base class and its subclasses are discussed later, but for now suffice it to say that every WebRequest object is associated with a WebRequestExecutor object whose main responsibility is to execute or make the request. c12.indd 457c12.indd 457 8/20/07 6:09:16 PM8/20/07 6:09:16 PM Chapter 12: Client-Server Communications 458 ❑ _invokeCalled : A Boolean value that ensures that the request is executed or made only once. ❑ _timeout : The field that specifies the request timeout. The request automatically gets canceled if the server response does not arrive within the time interval specified by this field. Listing 12-1: The Constructor of the WebRequest Class Sys.Net.WebRequest = function Sys$Net$WebRequest() { this._url = “”; this._headers = { }; this._body = null; this._userContext = null; this._httpVerb = null; this._executor = null; this._invokeCalled = false; this._timeout = 0; } Target URL As Listing 12-2 shows, the WebRequest class exposes a getter named get_url and a setter named set_url that you can use to get and set the target URL of the Web request. Listing 12-2: Getting and Setting the Target URL function Sys$Net$WebRequest$get_url() { return this._url; } function Sys$Net$WebRequest$set_url(value) { this._url = value; } HTTP Verb As Listing 12-3 shows, the WebRequest class exposes a getter named get_httpVerb and a setter named set_httpVerb that you can use to get and set the HTTP verb being used to send the Web request. If neither the HTTP verb nor the body of the Web request is specified, the GET HTTP verb will be used by default. Listing 12-3: Getting and Setting the HTTP Verb function Sys$Net$WebRequest$get_httpVerb() { if (this._httpVerb === null) { if (this._body === null) return “GET”; return “POST”; c12.indd 458c12.indd 458 8/20/07 6:09:16 PM8/20/07 6:09:16 PM Chapter 12: Client-Server Communications 459 } return this._httpVerb; } function Sys$Net$WebRequest$set_httpVerb(value) { this._httpVerb = value; } Body You invoke the get_body and set_body instance methods on the WebRequest object to get and set the body of the request, as shown in Listing 12-4 . Keep in mind that the body of a request is of type string . Listing 12-4: Getting and Setting the Body of the Web Request function Sys$Net$WebRequest$get_body() { return this._body; } function Sys$Net$WebRequest$set_body(value) { this._body = value; } Timeout You invoke the get_timeout and set_timeout instance methods on the WebRequest object to get and set the Web request timeout, as shown in Listing 12-5 . Note that the get_timeout method calls the get_defaultTimeout static method on an ASP.NET AJAX class named _WebRequestManager to return the default timeout if the timeout has been set to 0 . The _WebRequestManager class and its methods are discussed later, but for now suffice it to say that when you load your ASP.NET AJAX application, the ASP.NET AJAX client-side framework automatically creates an instance of the _WebRequestManager class. The main job of this instance is to manage all Web requests made to the server. Every ASP.NET AJAX application can have only one instance of the _WebRequestManager class. Listing 12-5: Getting and Setting the Web Request Timeout function Sys$Net$WebRequest$get_timeout() { if (this._timeout === 0) return Sys.Net.WebRequestManager.get_defaultTimeout(); return this._timeout; } function Sys$Net$WebRequest$set_timeout(value) { this._timeout = value; } c12.indd 459c12.indd 459 8/20/07 6:09:17 PM8/20/07 6:09:17 PM Chapter 12: Client-Server Communications 460 Web Request Executor The ASP.NET AJAX client-side framework includes a client class named WebRequestExecutor . The main job of a WebRequestExecutor object is to execute or make a specified Web request. You call the get_executor and set_executor methods on the WebRequest object to get and set the WebRequestExecutor object responsible for executing the Web request, as shown in Listing 12-6 . Listing 12-6: Getting and Setting the Web Request Executor function Sys$Net$WebRequest$get_executor() { return this._executor; } function Sys$Net$WebRequest$set_executor(value) { if (this._executor !== null && this._executor.get_started()) throw Error.invalidOperation(Sys.Res.setExecutorAfterActive); this._executor = value; this._executor._set_webRequest(this); } Note that the set_executor method invokes an internal method named _set_webRequest on the WebRequestExecutor object to specify the current WebRequest object as the WebRequest object that the WebRequestExecutor object must execute. Keep in mind that, by convention, any member of an ASP.NET AJAX class whose name begins with the underscore character (_ ) is considered an internal method. Consequently, you cannot call these methods from your client-side code. The set_executor setter method raises an exception if you attempt to set the executor of a WebRequest object after the request has been sent to the server. As you’ll see later, the WebRequestExecutor base class exposes a method named get_started that returns a Boolean value specifying whether the request has already been sent to the server. Headers Call the get_headers method shown in Listing 12-7 on the WebRequest object to get a reference to the _headers dictionary, which contains the names and values of the request headers. Listing 12-7: Getting the Web Request Headers function Sys$Net$WebRequest$get_headers() { return this._headers; } c12.indd 460c12.indd 460 8/20/07 6:09:17 PM8/20/07 6:09:17 PM Chapter 12: Client-Server Communications 461 Completed Event The WebRequest class exposes an event named completed , which is raised when the Web request has been completed. The WebRequest class follows the event implementation pattern discussed in the previous chapters to implement the completed event as follows: 1. It exposes a field of type EventHandlerList named _events that references an EventHandlerList object where all the event handlers registered for the events of the WebRequest class will be stored. 2. It exposes a getter method named get_eventHandlerList that returns a reference to this EventHandlerList object, as shown in Listing 12-8 . Listing 12-8: The get_events Method function Sys$Net$WebRequest$_get_eventHandlerList() { if (!this._events) this._events = new Sys.EventHandlerList(); return this._events; } 3. It implements a method named add_completed that calls the addHandler method on the EventHandlerList to add the specified function as an event handler for the completed event of the WebRequest object, as shown in Listing 12-9 . Listing 12-9: The add_completed Method function Sys$Net$WebRequest$add_completed(handler) { this._get_eventHandlerList().addHandler(“completed”, handler); } 4. It implements a method named remove_completed that calls the removeHandler method on the EventHandlerList to remove the specified event handler from the list of the event handlers registered for the completed event, as shown in Listing 12-10 . Listing 12-10: The remove_completed Method function Sys$Net$WebRequest$remove_completed(handler) { this._get_eventHandlerList().removeHandler(“completed”, handler); } 5. It implements a method named completed that raises the completed event, as shown in Listing 12-11 . c12.indd 461c12.indd 461 8/20/07 6:09:17 PM8/20/07 6:09:17 PM Chapter 12: Client-Server Communications 462 Listing 12-11: The completed Method function Sys$Net$WebRequest$completed(eventArgs) { var handler = Sys.Net.WebRequestManager._get_eventHandlerList().getHandler( “completedRequest”); if (handler) handler(this._executor, eventArgs); handler = this._get_eventHandlerList().getHandler(“completed”); if (handler) handler(this._executor, eventArgs); } This method calls the getHandler method on the EventHandlerList object. As discussed in the previous chapters, the getHandler method returns a reference to a JavaScript function whose invocation automatically invokes all event handlers registered for a specified event, which is the completed event in this case: handler = this._get_eventHandlerList().getHandler(“completed”); if (handler) handler(this._executor, eventArgs); As you’ll see later, the _ WebRequestManager class exposes an event named completedRequest , which maps to the completed event of the WebRequest object being executed. In other words, the _ WebRequestManager class must raise its completedRequest event when the WebRequest object raises its completed event. The _ WebRequestManager class also uses the same event implementation pattern to implement the completedRequest event, which means that this class also exposes an _events field of type EventHandlerList that references an EventHandlerList object containing all event handlers registered for the events of the WebRequestManager object. As Listing 12-11 shows, the completed method of the WebRequest object calls the getHandler method on the EventHandlerList object that contains the event handlers registered for the events of the WebRequestManager object to return a reference to the JavaScript function whose invocation automatically invokes all the event handlers registered for the completedRequest event. The completed method then invokes this JavaScript function, passing in a reference to the WebRequestExecutor object. This tricks the event handlers registered for the completedRequest event of the WebRequestManager object into thinking that the WebRequestExecutor object itself raised the event and called these handlers. Invoking a Web Request You call the invoke instance method on the WebRequest object that represents a Web request to make the request to the server. As Listing 12-12 shows, this method delegates the responsibility of executing the request to the executeRequest method of the current WebRequestManager instance. (The _ WebRequestManager class and its methods are discussed later in this chapter.) Note that the WebRequest object uses an internal Boolean flag named _invokeCalled to ensure that the same request is not executed more than once. c12.indd 462c12.indd 462 8/20/07 6:09:18 PM8/20/07 6:09:18 PM Chapter 12: Client-Server Communications 463 Listing 12-12: Invoking a Web Request function Sys$Net$WebRequest$invoke() { if (this._invokeCalled) throw Error.invalidOperation(Sys.Res.invokeCalledTwice); Sys.Net.WebRequestManager.executeRequest(this); this._invokeCalled = true; } WebRequestExecutor As discussed in the previous section, every ASP.NET AJAX Web request is represented by an instance of the WebRequest class. The ASP.NET AJAX client-side framework includes a class named WebRequestExecutor whose sole responsibility is to execute a given Web request represented by a given WebRequest object. The following sections discuss the main members of the WebRequestExecutor class. Constructor As you can see in Listing 12-13 , the WebRequestExecutor constructor defines the following two fields: ❑ _webRequest : This field references the WebRequest object that the WebRequestExecutor object executes. ❑ _ resultObject : This field references the JSON object that contains the data received from the server. For example, this can be the JSON representation of a DataTable object and, consequently, can be passed into the parseFromJson static method of the DataTable class to deserialize the DataTable object. Listing 12-13: The Constructor of the WebRequestExecutor Class Sys.Net.WebRequestExecutor = function Sys$Net$WebRequestExecutor() { this._webRequest = null; this._resultObject = null; } WebRequest You invoke the get_webRequest instance method on the WebRequestExecutor object responsible for executing a given request to get a reference to the WebRequest object that represents the request, as shown in Listing 12-14 . c12.indd 463c12.indd 463 8/20/07 6:09:18 PM8/20/07 6:09:18 PM Chapter 12: Client-Server Communications 464 Listing 12-14: Getting and Setting the WebRequest Object function Sys$Net$WebRequestExecutor$get_webRequest() { return this._webRequest; } function Sys$Net$WebRequestExecutor$_set_webRequest(value) { if (this.get_started()) throw Error.invalidOperation(String.format(Sys.Res.cannotCallOnceStarted, ‘set_webRequest’)); this._webRequest = value; } As this code listing shows, the WebRequestExecutor class contains an internal setter method named _set_webRequest that specifies the WebRequest object that the current WebRequestExecutor must execute. You should never call this method to set the WebRequest object for a WebRequestExecutor object. Instead, you must call the set_executor instance method on the WebRequest object to specify its associated WebRequestExecutor object. As previously shown in Listing 12-6 , the set_executor method of the WebRequest object calls the _set_webRequest internal method under the hood to register itself with the specified WebRequestExecutor . The _set_webRequest internal method first calls the get_started method to return a Boolean value that specifies whether the request has already been made. If the request has already been made, it raises an exception. get_started The WebRequestExecutor exposes a method named get_started that you can call on the WebRequestExecutor object to check whether the request has already been sent to the server. As Listing 12-15 shows, the WebRequestExecutor base class does not implement this method. Instead, the subclasses of the WebRequestExecutor base class must implement this method to include the logic necessary to determine whether the request has already been made. Listing 12-15: The get_started Method function Sys$Net$WebRequestExecutor$get_started() { throw Error.notImplemented(); } get_responseAvailable You can call the get_responseAvailable method on a WebRequestExecutor object to return a Boolean value that specifies whether the response from the server has arrived, as shown in Listing 12-16 . It is the responsibility of the subclasses of the WebRequestExecutor base class must implement this method to incorporate the necessary logic. c12.indd 464c12.indd 464 8/20/07 6:09:18 PM8/20/07 6:09:18 PM Chapter 12: Client-Server Communications 465 Listing 12-16: The get_responseAvailable Method function Sys$Net$WebRequestExecutor$get_responseAvailable() { throw Error.notImplemented(); } get_timedOut You can call the get_timedOut method on a WebRequestExecutor object to return a Boolean value that specifies whether the specified request has timed out, as shown in Listing 12-17 . Again it is the responsibility of the subclasses of the WebRequestExecutor base class to implement this method. Listing 12-17: The get_timedOut Method function Sys$Net$WebRequestExecutor$get_timedOut() { throw Error.notImplemented(); } get_aborted You can invoke this method on a WebRequestExecutor object to return a Boolean value that specifies whether the Web request has aborted, as shown in Listing 12-18 . Once again it is the responsibility of the subclasses of the WebRequestExecutor base class to implement this method. Listing 12-18: The get_aborted Method function Sys$Net$WebRequestExecutor$get_aborted() { throw Error.notImplemented(); } get_responseData You can invoke this method on a WebRequestExecutor object to return a string that contains the data received from the server as shown in Listing 12-19 . The subclasses of the WebRequestExecutor base class must implement this method as well. Listing 12-19: The get_responseData Method function Sys$Net$WebRequestExecutor$get_responseData() { throw Error.notImplemented(); } c12.indd 465c12.indd 465 8/20/07 6:09:19 PM8/20/07 6:09:19 PM Chapter 12: Client-Server Communications 466 get_statusCode You can invoke this method on a WebRequestExecutor object to return an integer that specifies the status code of the server response as shown in Listing 12-20 . The subclasses of the WebRequestExecutor base class must implement this method. Listing 12-20: The get_statusCode Method function Sys$Net$WebRequestExecutor$get_statusCode() { throw Error.notImplemented(); } get_statusText You can invoke this method on a WebRequestExecutor object to return a string that contains the status text of the server response as shown in Listing 12-21 . The subclasses of the WebRequestExecutor base class must implement this method. Listing 12-21: The get_statusText Method function Sys$Net$WebRequestExecutor$get_statusText() { throw Error.notImplemented(); } get_xml You can invoke this method on a WebRequestExecutor object to return an XML document that contains the data received from the server as shown in Listing 12-22 . The subclasses of the WebRequestExecutor base class must implement this method. Listing 12-22: The get_xml Method function Sys$Net$WebRequestExecutor$get_xml() { throw Error.notImplemented(); } get_object You can invoke this method on a WebRequestExecutor object to return a JavaScript object that contains the data received from the server as shown in Listing 12-23 . c12.indd 466c12.indd 466 8/20/07 6:09:19 PM8/20/07 6:09:19 PM [...]... it’s a POST but no Content-Type was specified, default to // application/x-www-form-urlencoded if ((headers === null) || !headers[‘Content-Type’]) this._xmlHttpRequest.setRequestHeader(‘Content-Type’, ‘application/x-www-form-urlencoded’); // If POST with no body, default to “”(FireFox needs this) if (!body) body = “”; 480 c12.indd 480 8/20/07 6:09:23 PM Chapter 12: Client-Server Communications } var... When an ASP.NET AJAX application is loading, the ASP.NET AJAX client-side framework instantiates a single instance of an ASP.NET AJAX client class named _WebRequestManager and assigns the instance to a global variable named Sys.Net.WebRequestManager You cannot create a new instance of this class Instead, you use the WebRequestManager to get a reference to the instance that the ASP.NET AJAX client-side... (continued) 489 c12.indd 489 8/20/07 6:09:26 PM Chapter 12: Client-Server Communications Listing 1 2-5 6 (continued) Submit Your... null; } } XMLDOM The XMLDOM encapsulates the browser-specific logic that creates an XML document As Listing 1 2-3 9 shows, the constructor of this class takes a string that contains the XML data and returns a reference to an XMLDOM document that contains the data 474 c12.indd 474 8/20/07 6:09:21 PM Chapter 12: Client-Server Communications Listing 1 2-3 9: The XMLDOM Class window.XMLDOM = function window$XMLDOM(markup)... If the HTTP verb is POST and the Content-Type header has not been specified, executeRequest calls the setRequestHeader method on the XMLHttpRequest object to use application/x-www-formurlencoded as the value of the Content-Type header: if ((headers === null) || !headers[‘Content-Type’]) this._xmlHttpRequest.setRequestHeader(‘Content-Type’, ‘application/x-www-form-urlencoded’); Next, executeRequest calls... this._defaultExecutorType = “Sys.Net.XMLHttpExecutor”; } This constructor defines the following three fields: ❑ _this: This field references the instance of the class that the ASP.NET AJAX client-side framework creates for the current application 468 c12.indd 468 8/20/07 6:09:19 PM Chapter 12: Client-Server Communications ❑ _defaultTimeout: This field specifies the default timeout for all the Web requests made in... the XMLHttpRequest object, as shown in Listing 1 2-4 1 Listing 1 2-4 1: The _onReadyStateChange Method this._onReadyStateChange = function () { if (_this._xmlHttpRequest.readyState === 4 /*complete*/) { _this._clearTimer(); _this._responseAvailable = true; _this._webRequest.completed(Sys.EventArgs.Empty); 476 c12.indd 476 8/20/07 6:09:22 PM Chapter 12: Client-Server Communications if (_this._xmlHttpRequest... window.clearTimeout(_this._timer); _this._timer = null; } } _onTimeout The XMLHttpExecutor object calls the _onTimeout method when the request times out, as shown in Listing 1 2-4 3 477 c12.indd 477 8/20/07 6:09:22 PM Chapter 12: Client-Server Communications Listing 1 2-4 3: The _onTimeout Method this._onTimeout = function this$_onTimeout() { if (!_this._responseAvailable) { _this._clearTimer(); _this._timedOut = true; _this._xmlHttpRequest.onreadystatechange... _this._xmlHttpRequest = null; 478 c12.indd 478 8/20/07 6:09:22 PM Chapter 12: Client-Server Communications get_timedOut You can call the get_timedOut method on the XMLHttpExecutor object responsible for executing a WebRequest object to access the value of the _timedOut Boolean field (see Listing 1 2-4 4) This field specifies whether the current request has timed out Listing 1 2-4 4: The get_timedOut Method function... XMLHttpExecutor object responsible for executing a WebRequest object to access the value of the _aborted Boolean field (see Listing 1 2-4 7) This field specifies whether the current request has been aborted 479 c12.indd 479 8/20/07 6:09:23 PM Chapter 12: Client-Server Communications Listing 1 2-4 7: The get_aborted Method function Sys$Net$XMLHttpExecutor$get_aborted() { /// return this._aborted; . in Listing 1 2-1 1 . c12.indd 461c12.indd 461 8/20/07 6:09:17 PM8/20/07 6:09:17 PM Chapter 12: Client-Server Communications 462 Listing 1 2-1 1: The completed Method function Sys $Net$ WebRequest$completed(eventArgs). in Listing 1 2-2 3 . c12.indd 466c12.indd 466 8/20/07 6:09:19 PM8/20/07 6:09:19 PM Chapter 12: Client-Server Communications 467 Listing 1 2-2 3: The get_object Method function Sys $Net$ WebRequestExecutor$get_object() { . Error.notImplemented(); } WebRequestManager When an ASP. NET AJAX application is loading, the ASP. NET AJAX client-side framework instantiates a single instance of an ASP. NET AJAX client class named _WebRequestManager