随笔-312  评论-12034  文章-2  trackbacks-256

本文来自《ASP.NET AJAX程序设计 第II卷:客户端Microsoft AJAX Library相关》的第三章《异步调用Web Service和页面中的类方法》,请同时参考本章的其他文章

 

3.5 异步通讯层生成的客户端代理类

在前面几节中,我们已经看到了ASP.NET AJAX异步通讯层为Web Service生成的客户端异步调用代理的基本使用方法。这里有必要再详细介绍一下该客户端代理的功能,并做以总结。

如下代码就是ASP.NET AJAX异步通讯层为本章第1节中那个简单的Web Service所生成的客户端调用代理(代码经过格式化):

var SimpleWebService = function() {
    SimpleWebService.initializeBase(this);
    this._timeout = 0;
    this._userContext = null;
    this._succeeded = null;
    this._failed = null;
}
 
SimpleWebService.prototype = {
    SayHello: 
        function(name,succeededCallback, failedCallback, userContext) {
            return this._invoke(
                SimpleWebService.get_path(), 
                'SayHello',
                false,
                {name:name},
                succeededCallback,
                failedCallback,
                userContext
            ); 
        }
}
SimpleWebService.registerClass('SimpleWebService',Sys.Net.WebServiceProxy);
 
SimpleWebService._staticInstance = new SimpleWebService();
 
SimpleWebService.set_path = function(value) { 
    var e = Function._validateParams(arguments, [{name: 'path', type: String}]); 
    if (e) 
        throw e; 
    SimpleWebService._staticInstance._path = value; 
}
SimpleWebService.get_path = function() { 
    return SimpleWebService._staticInstance._path; 
}
 
SimpleWebService.set_timeout = function(value) { 
    var e = Function._validateParams(arguments, [{name: 'timeout', type: Number}]); 
    if (e) 
        throw e; 
    if (value < 0) { 
        throw Error.argumentOutOfRange('value', value, Sys.Res.invalidTimeout); 
    }
    SimpleWebService._staticInstance._timeout = value; 
}
SimpleWebService.get_timeout = function() { 
    return SimpleWebService._staticInstance._timeout; 
}
 
SimpleWebService.set_defaultUserContext = function(value) { 
    SimpleWebService._staticInstance._userContext = value; 
}
SimpleWebService.get_defaultUserContext = function() { 
    return SimpleWebService._staticInstance._userContext; 
}
 
SimpleWebService.set_defaultSucceededCallback = function(value) { 
    var e = Function._validateParams(arguments, [{name: 'defaultSucceededCallback', type: Function}]); 
    if (e) 
        throw e; 
    SimpleWebService._staticInstance._succeeded = value; 
}
SimpleWebService.get_defaultSucceededCallback = function() { 
    return SimpleWebService._staticInstance._succeeded; 
}
 
SimpleWebService.set_defaultFailedCallback = function(value) { 
    var e = Function._validateParams(arguments, [{name: 'defaultFailedCallback', type: Function}]); 
    if (e) 
        throw e; 
    SimpleWebService._staticInstance._failed = value; 
}
SimpleWebService.get_defaultFailedCallback = function() { 
    return SimpleWebService._staticInstance._failed; 
}
 
SimpleWebService.set_path("/Chapter03/Services/SimpleWebService.asmx");
 
SimpleWebService.SayHello= function(name,onSuccess,onFailed,userContext) {
    SimpleWebService._staticInstance.SayHello(name,onSuccess,onFailed,userContext); 
}

可以看到,ASP.NET AJAX异步通讯层为Web Service生成的客户端异步调用代理类各不相同,但均继承于Sys.Net.WebServiceProxy类,以实现调用Web Service,而Sys.Net.WebServiceProxy类则又在内部使用Sys.Net.WebRequest组件完成实际的HTTP请求。

调用生成的Web Service客户端代理中方法的语法如下:

[NameSpace].[ClassName].[MethodName](param1, param2 …, onSucceeded, onFailed, userContext)

我们也可以先创建一个Web Service客户端代理的实例,然后用该实例调用Web Service的客户端代理:

var myGenaratedWebServiceProxy = new [NameSpace].[ClassName]();
myGenaratedWebServiceProxy.[MethodName](param1, param2 …, onSucceeded, onFailed, userContext);

其中各个通配符以及参数的说明如表3-2所示。

表3-2 Web Service客户端代理调用语法中的通配符和参数

  1. 通配符/参数:描述
  2. [NameSpace]:服务器端Web Service的命名空间。若没有显式命名空间声明,则该部分可以省略
  3. [ClassName]:服务器端Web Service的类名
  4. [MethodName]:定义在服务器端Web Service中的、将要被调用的方法名
  5. param1 param2 … param n:将要调用的方法的参数列表。其中参数的个数、顺序要与Web Service中方法参数的定义严格保持一致
  6. onSucceeded:成功调用Web Service之后的回调函数,该参数为可选
  7. onFailed:调用Web Service失败时的回调函数,该参数为可选
  8. userContext:调用Web Service时传递的用户上下文对象,该参数为可选

注意:对于onSucceeded、onFailed和userContext三个可选参数,若省略了位置靠前的某个参数而指定了靠后的参数,那么一定要使用null占位。例如,在发起某次调用时,我们希望跳过onFailed参数,并指定userContext,那么调用语法将类似如下所示:

SomeNamespace.SomeClass.SomeMethod(param1, param2, onSucceeded, null, contextObj);

ASP.NET AJAX异步通讯层为Web Service生成的客户端代理组件还允许我们设置默认的onSucceeded、onFailed和userContext参数,分别通过set_defaultFailedCallback()、set_defaultFailedCallback()和set_defaultUserContext()方法完成。请参考如下代码:

SomeNamespace.SomeClass.set_defaultSucceededCallback(defaultSucceededCallback);
SomeNamespace.SomeClass.set_defaultFailedCallback(defaultFailedCallback);
SomeNamespace.SomeClass.set_defaultUserContext("default context");

或者:

var theProxyInstance = new SomeNamespace.SomeClass();
theProxyInstance.set_defaultSucceededCallback(defaultSucceededCallback);
theProxyInstance.set_defaultFailedCallback(defaultFailedCallback);
theProxyInstance.set_defaultUserContext("default context");

设置了默认的回调函数以及用户上下文对象之后,若调用时省略了某一项内容,则代理组件将自动选择并使用默认的设置代替。若是调用时仍明确指定了某项内容,则该设定将覆盖默认的设定。在实际开发中,合理地使用默认的onSucceeded、onFailed和userContext参数会极大地降低程序的代码量,并让程序逻辑更加清晰。

除此之外,ASP.NET AJAX异步通讯层为Web Service生成的客户端代理组件提供了超时的配置:通过其set_timeout()方法,即可设定调用过程的最长等待时间(单位为毫秒)。请参考如下代码:

SomeNamespace.SomeClass.set_timeout(3000);

或者:

var theProxyInstance = new SomeNamespace.SomeClass();
theProxyInstance.set_timeout(3000);

完整的成功回调函数的签名将类似如下所示:

function onSucceeded(result, userContext, methodName) {
    // ......
}

其中result参数代表Web Service的返回值;userContext参数代表用户上下文对象;methodName参数代表调用的Web Service方法的名称。userContext和methodName参数均可在该回调函数中提供一些关于原始调用者的额外信息。

完整的失败回调函数的签名将类似如下所示:

function onFailed(error, userContext, methodName){
    // ......
}

其中error参数是一个Sys.Net.WebServiceError对象,代表导致本次异步调用失败的异常;userContext参数代表用户上下文对象;methodName参数代表调用的Web Service方法的名称。其中userContext和methodName参数均可在该回调函数中提供一些关于原始调用者的额外信息。

提示:成功回调函数和失败回调函数可以选择任何的名字,并不限于书中提到的onSucceeded()和onFailed()。

 

3.6 使用HTTP GET进行调用

在使用ASP.NET AJAX异步通讯层对Web Service进行异步调用时,默认应用的是HTTP POST方式。但为了提供足够的灵活性,ASP.NET AJAX异步通讯层同样允许我们使用HTTP GET进行调用。

使用HTTP GET进行调用时,方法的参数均被序列化成JSON字符串,然后经过URL编码并添加至URL后面送回给服务器处理。关于GET和默认的POST方式的比较,在本卷第2章中已经有过详细介绍,这里不再重复。

若想以HTTP GET的方式对某个Web Service中的方法进行调用,那么只要为该方法添加[ScriptMethod(UseHttpGet = true)]属性即可。例如对于本章第1节中的示例程序,我们可以按照如下代码修改服务器端Web Service中方法的定义,注意其中粗体部分:

[WebMethod]
[ScriptMethod(UseHttpGet = true)]
public string SayHelloUsingGET(string name)
{
    return string.Format("Hello {0}!", name);
}

再次运行该示例程序,并打开HTTP嗅探器,可以看到本次异步调用确实使用了HTTP GET。如图3-9所示。

图3-9使用HTTP GET调用Web Service

注意:在使用HTTP GET请求Web Service时,特别要注意安全性问题。一般来讲,只有在没有暴露敏感信息且没有关键操作(例如删除/更新数据)等安全的情况下,才可以使用HTTP GET。

posted on 2007-06-08 07:44 Dflying Chen 阅读(5220) 评论(13)  编辑 收藏 网摘 所属分类: ASP.NET AJAX (Atlas)

评论:
#1楼 2007-06-08 08:55 | Anthan      
文章开始处那一段Web Service所生成的客户端调用代理的代码看得有点晕,呵呵。
不过理解原理以后再回头看第一卷的东西有种豁然开朗的感觉
ps:早起的人儿有沙发抢,嘿嘿

  回复  引用  查看    
#2楼[楼主] 2007-06-08 09:46 | Dflying Chen      
@Anthan
:)

  回复  引用  查看    
#3楼 2007-06-08 10:14 | MK2      
如何设置一个全局的Ajax调用Web Service的默认错误处理呢?
  回复  引用  查看    
#4楼[楼主] 2007-06-08 10:34 | Dflying Chen      
@MK2
每个都设置一下吧,呵呵,写段代码遍历一下所有的Web Service代理类

  回复  引用  查看    
#5楼 2007-06-09 16:54 | wang[未注册用户]
文章开始处那一段Web Service所生成的客户端调用代理的代码在哪可以看到啊?
  回复  引用    
#6楼[楼主] 2007-06-09 20:45 | Dflying Chen      
@wang
该脚本已经被下载到了客户端浏览器中

  回复  引用  查看    
#7楼 2007-06-11 22:54 | wang[未注册用户]
原来脚本是下到Temporary Internet Files目录下了晕
  回复  引用    
#8楼[楼主] 2007-06-12 10:38 | Dflying Chen      
@wang
在VS中也可以看到的

  回复  引用  查看    
#9楼 2007-07-04 22:25 | swx[未注册用户]
为什么类似这些SimpleWebService.set_path 属性没有放到prototype中?可以放进去吗?
  回复  引用    
#10楼 2007-07-11 17:14 | winnerzone      
看完了~谢谢
  回复  引用  查看    
#11楼[楼主] 2007-07-11 19:12 | Dflying Chen      
@swx
当然可以放入了,不过只有一个实例,也无所谓了:)

  回复  引用  查看    
#12楼[楼主] 2007-07-11 19:12 | Dflying Chen      
@winnerzone
:)

  回复  引用  查看    
#13楼 2007-11-18 22:16 | Delete[未注册用户]
非常感谢您。
前面的代码都看懂了,就是有个细节不太懂:
var e = Function._validateParams(arguments, [{name: 'path', type: String}]);
这一句中Function和_arguments是哪来的呀?
是javascript里固有的还是ASP.net AJAX扩展的呢?

  回复  引用    



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 776042





相关文章:

相关链接: