MSDN Magazine - December 2007 - (Page 42) Figure 6 Web Service Proxy Class Type.registerNamespace(‘MsdnMag’); MsdnMag.SimpleService = function() { MsdnMag.SimpleService.initializeBase(this); this._timeout = 0; this._userContext = null; this._succeeded = null; this._failed = null; } MsdnMag.SimpleService.prototype = { DoSomething : function(succeededCallback, failedCallback, userContext) { return this._invoke(MsdnMag.SimpleService.get_path(), ‘DoSomething’, false, {}, succeededCallback, failedCallback, userContext); } } MsdnMag.SimpleService.registerClass( ‘MsdnMag.SimpleService’, Sys.Net.WebServiceProxy); MsdnMag.SimpleService._staticInstance = new MsdnMag.SimpleService(); MsdnMag.SimpleService.DoSomething = function(onSuccess,onFailed,userContext) { MsdnMag.SimpleService._staticInstance.DoSomething( onSuccess, onFailed, userContext); } fied name of the service class. The object also has the same set of methods. Methods, though, have an extended signature that encompasses additional parameters in addition to the standard set of input arguments. In particular, each method adds two callback functions to allow user code the ability to handle a successful or failed call, plus an optional object that represents the context of the call. The proxy object derives from the Sys.Net.WebServiceProxy Microsoft AJAX Library class. Figure 6 shows a fragment of a service proxy class. For performance reasons, a proxy class is a singleton that executes each of its methods asynchronously in a callback model. In this code, the _invoke method ends up creating a Web request and—not a minor point—sets the content type to application/json, a required setting for the ASP.NET AJAX runtime. Here’s a sample fragment: var request = new Sys.Net.WebRequest(); request.get_headers()[‘Content-Type’] = ‘application/json; charset=utf-8’; A timeout is automatically set and controlled through an internal timer. Furthermore, the proxy registers a handler for the completed event of the Web request. When the event fires, the system-provided code checks the response. If all went well, the proxy invokes the user-defined success callback. Otherwise, it invokes the failure callback and passes it information about the error that occurred, as in this code snippet: var error = response.getResponseHeader(“jsonerror”); var errorObj = (error === “true”); if (errorObj) err = new Sys.Net.WebServiceError(false, result.Message, result.StackTrace, result.ExceptionType); onFailure(err, userContext, methodName); point is, what other techniques and alternatives exist to justify the creation of a custom executor? An additional executor could use a dynamically created, invisible IFRAME to download any response sent back by any URL. You should notice that, when using XMLHttpRequest, you’re limited to the so-called same-origin-policy that most browsers implement. In practice, it means that browsers do not allow scripted calls to URLs located outside the domain of the current page. When using XMLHttpRequest, you can’t call into, say, contoso1.com from contoso2.com. You can accomplish this, instead, using an IFRAME to grab the response and then parse it to any suitable JavaScript object. To write an IFRAME-based executor, you should start with a Microsoft AJAX Library object that inherits from Sys.Net.WebRequestExecutor and implements all of its abstract members. As for parsing the response into a usable memory object, you might want to define a request-specific parser component that provides a custom behavior under a common programming interface. If the execution of the service method results in an unhandled exception, the message that is associated with the exception, its stacktrace, and its type are carried back to the client and composed into a WebServiceError JavaScript object that the failure callback can work with. The Partial Rendering Engine The key object for partial rendering is PageRequestManager, in the Sys.WebForms namespace. The code that initializes the object is transparently inserted in any client page that includes at least one UpdatePanel control. If you view the source of such a page, you’ll find a piece of script like the following: Sys.WebForms.PageRequestManager._initialize( ‘ScriptManager1’, document.getElementById(‘form1’)); Proxy Objects for Script Services Scriptable services need some JavaScript wrapper code in order to be invoked. A script-based proxy class can therefore be generated that provides a public programming interface that is nearly identical to that of the original service—be it a classic ASP.NET Web service or a Windows Communication Foundation (WCF) service. The proxy class is linked to the page via a script tag that is bound to a specific URL: http://www.yourserver.com/service.asmx/js The name of the proxy object is the same as the fully quali42 msdnmagazine Cutting Edge The ID of the ScriptManager control as well as the ID of the form are arbitrary. The _initialize method on the PageRequestManager does two main things. First, it creates the unique instance of the object to serve all needs in the page lifecycle. Second, it registers a script handler for the form’s submit event. In this way, you end up having a common piece of code to intercept any type of postback—regular postbacks done via the browser, cross-page postbacks, and postbacks commanded through the DOM. The goal of the submit handler is stopping the browser’s default action and replacing the form submission with an AJAX request managed through the default Web request executor. http://ASP.NET http://ASP.NET http://www.yourserver.com/service.asmx/js
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.