之前遇到一个要求需要能够取消一个正在进行中的Web Service这也是我第一次遇到这个功能不过不难我想既然ASPNET AJAX的客户端与服务器端通信完全通过Microsoft AJAX Library的异步通信层进行那么我们只要得到正在请求Web Service的SysNetWebRequest对象调用其abort方法就可以了但是究竟应该如何得到这个对象呢?于是我粗略地阅读了一下代码 首先假设有如下的Web Service方法定义(DemoServiceasmx)
[ScriptService]public class DemoService : SystemWebServicesWebService{ [WebMethod] public string DemoMethod() { return Hello World; } } 访问DemoServiceasmx/jsdebug(或者将其使用ScriptManager引用到页面中之后)就能够得到如下的代理(片断经过排版)类 var DemoService = function(){ DemoServiceinitializeBase(this); this_timeout = ; this_userContext = null; this_succeeded = null; this_failed = null;}DemoServiceprototype ={ DemoMethod:function(succeededCallback failedCallback userContext) { return this_invoke( DemoServiceget_path() DemoMethod false {} succeededCallback failedCallback userContext); }}DemoServiceregisterClass(DemoServiceSysNetWebServiceProxy); 显然这个代理类继承了SysNetWebServiceProxy类于是我就把目光转向了其中的_invoke方法 function Sys$Net$WebServiceProxy$_invoke( servicePath methodName useGet params onSuccess onFailure userContext) { // validation omitted return SysNetWebServiceProxyinvoke( servicePath methodName useGet params onSuccess onFailure userContext thisget_timeout());} 这下又将操作委托给了SysNetWebServiceProxyinvoke静态方法继续看代码 SysNetWebServiceProxyinvoke = function Sys$Net$WebServiceProxy$invoke( servicePath methodName useGet params onSuccess onFailure userContext timeout) { // validation omitted // Create a web request to make the method call var request = new SysNetWebRequest(); // preparing request omitted requestinvoke(); function onComplete(response eventArgs) { // method body omitted } return request;} 嗨这不就是我所需要的SysNetWebRequest对象吗?原来想要得到这个对象那么简单于是我就写下了下面的代码 var request = DemoServiceDemoMethod(onComplete); 然后在必要时 requestabort(); 执行出现了错误request为undefined为什么DemoMethod方法调用没有返回request对象?跟蹤了代码之后不大不小地晕了一下原来问题出在这里 DemoService_staticInstance = new DemoService();DemoServiceDemoMethod = function(onSuccessonFaileduserContext){ DemoService_staticInstanceDemoMethod(onSuccessonFaileduserContext);} 虽然早就知道Web Service代理会在类上创建一个Singleton对象并且创建静态方法再委托给那个实例上的相应方法却一直没有意识到这个细节在上面的静态方法中居然是直接调用了DemoMethod方法却没有将结果返回出来真让我哭笑不得了一下 不过问题时非常容易解决的只要使用如下的方式在客户端调用WebService方法就可以了 var request = DemoService_staticInstanceDemoMethod(onComplete); 不过这个做法似乎……有些奇怪?那么您也可以这样 var demoService = new DemoService();var request = demoServiceDemoMethod(onComplete); 在这里重新创建一个demoService对象似乎有些多余不过在某些时候也是非常有用的做法例如您需要将操作分为两类一类的超时时间为秒而另一类为秒因此您就可以创建两个代理对象分别设置不同的超时时间因为超时时间我们只能在Service的级别上设置而不能在调用方法时指定 |