老赵点滴


  先做人,再做技术人员,最后做程序员。
  我的理想:“让外国人看中国人写的技术书籍和文章”。Try as I might
posts - 290, comments - 10754, trackbacks - 146, articles - 6
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

  之前遇到一个要求,需要能够取消一个正在进行中的Web Service。这也是我第一次遇到这个功能,不过不难,我想。既然ASP.NET AJAX的客户端与服务器端通信完全通过Microsoft AJAX Library的异步通信层进行,那么我们只要得到正在请求Web Service的Sys.Net.WebRequest对象,调用其abort方法就可以了。但是究竟应该如何得到这个对象呢?于是我粗略地阅读了一下代码。

  首先假设有如下的Web Service方法定义(DemoService.asmx):

[ScriptService]
public class DemoService  : System.Web.Services.WebService
{
    [WebMethod]
    public string DemoMethod()
    {
        return "Hello World";
    }    
}

  访问DemoService.asmx/jsdebug(或者将其使用ScriptManager引用到页面中之后)就能够得到如下的代理(片断、经过排版)类。

var DemoService = function()
{
    DemoService.initializeBase(this);
    this._timeout = 0;
    this._userContext = null;
    this._succeeded = null;
    this._failed = null;
}
DemoService.prototype =
{
    DemoMethod:function(succeededCallback, failedCallback, userContext)
    {
        return this._invoke(
            DemoService.get_path(),
            'DemoMethod',
            false,
            {},
            succeededCallback,
            failedCallback,
            userContext);
    }
}
DemoService.registerClass('DemoService',Sys.Net.WebServiceProxy);
...

  显然,这个代理类继承了Sys.Net.WebServiceProxy类,于是我就把目光转向了其中的_invoke方法:

function Sys$Net$WebServiceProxy$_invoke(
    servicePath, methodName, useGet, params, onSuccess, onFailure, userContext) {

    // validation omitted
    ...
    
    return Sys.Net.WebServiceProxy.invoke(
        servicePath,
        methodName,
        useGet,
        params,
        onSuccess,
        onFailure,
        userContext,
        this.get_timeout());
}

  这下又将操作委托给了Sys.Net.WebServiceProxy.invoke静态方法,继续看代码:

Sys.Net.WebServiceProxy.invoke = 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 Sys.Net.WebRequest();

    // preparing request omitted
    ...

    request.invoke();

    function onComplete(response, eventArgs) {
        // method body omitted
    }

    return request;
}

  嗨,这不就是我所需要的Sys.Net.WebRequest对象吗?原来想要得到这个对象那么简单,于是我就写下了下面的代码:

var request = DemoService.DemoMethod(onComplete);

  然后在必要时:

request.abort();

  执行,出现了错误:request为undefined,为什么DemoMethod方法调用没有返回request对象?跟踪了代码之后,不大不小地晕了一下,原来问题出在这里:

DemoService._staticInstance = new DemoService();
...
DemoService.DemoMethod = function(onSuccess,onFailed,userContext)
{
    DemoService._staticInstance.DemoMethod(onSuccess,onFailed,userContext);
}

  虽然早就知道Web Service代理会在类上创建一个Singleton对象,并且创建静态方法再委托给那个实例上的相应方法,却一直没有意识到这个细节。在上面的静态方法中,居然是直接调用了DemoMethod方法,却没有将结果返回出来,真让我哭笑不得了一下。

  不过问题时非常容易解决的,只要使用如下的方式在客户端调用WebService方法就可以了:

var request = DemoService._staticInstance.DemoMethod(onComplete);

  不过这个做法似乎……有些奇怪?那么您也可以这样:

var demoService = new DemoService();
var request = demoService.DemoMethod(onComplete);

  在这里,重新创建一个demoService对象似乎有些多余,不过在某些时候也是非常有用的做法。例如,您需要将操作分为两类,一类的超时时间为5秒,而另一类为10秒,因此您就可以创建两个代理对象,分别设置不同的超时时间。因为超时时间我们只能在Service的级别上设置,而不能在调用方法时指定。

Feedback

#1楼    回复  引用    

2007-07-23 23:37 by zzz [未注册用户]
沙发。。。。
支持老赵。。。。

#2楼    回复  引用  查看    

2007-07-23 23:58 by 若寒      
写得太好了.
谢谢!

#3楼    回复  引用    

2007-07-24 08:15 by long [未注册用户]
挤进前10

#4楼    回复  引用    

2007-07-24 08:52 by blue [未注册用户]
加油啊老赵同志!

#5楼    回复  引用  查看    

2007-07-24 09:28 by 淡泊江湖      
笔耕不辍,UP!

#6楼    回复  引用  查看    

2007-07-24 09:39 by Anders Liu      
漂亮!支持老赵

#7楼    回复  引用  查看    

2007-07-24 10:07 by 老刘.      
:)

#8楼    回复  引用  查看    

2007-07-24 10:08 by 一帆(老鼠粮仓之路)      
一个很不错的小伙啊

#9楼    回复  引用  查看    

2007-07-24 10:58 by Leepy      
好细致啊,老赵!

#10楼 [楼主]   回复  引用  查看    

2007-07-24 11:07 by Jeffrey Zhao      
@若寒
@zzz
@淡泊江湖
@Anders Liu
@老刘.
@一帆(老鼠粮仓之路)
谢谢支持:)

#11楼 [楼主]   回复  引用  查看    

2007-07-24 11:07 by Jeffrey Zhao      
@Leepy
正好遇到了吧,其实我觉得这样的问题价值不大。

#12楼    回复  引用  查看    

2007-07-24 12:03 by xiao_p      
对老赵同志的追捧要适可而止了哈,我们不能过度崇拜 :P :-)

#13楼    回复  引用    

2007-07-24 13:30 by zzzz [未注册用户]
绝不过度崇拜。
只是崇拜过度而已!

#14楼    回复  引用  查看    

2007-07-24 13:58 by volnet(可以叫我大V)      
怎么所有的评论都是对老赵的追捧啊~呵呵,社区不提倡个人崇拜噢~
老赵我支持你~~~~·晕死~

#15楼    回复  引用  查看    

2007-07-24 15:34 by bighope      
老赵本家哦,支持,继续向你学习!

#16楼    回复  引用  查看    

2007-07-24 16:47 by 流言蜚语      
不顶,对不起党国!更对不起楼上这么多哥们

#17楼 [楼主]   回复  引用  查看    

2007-07-24 17:49 by Jeffrey Zhao      
我说……好像夸张了一点,呵呵……

#18楼    回复  引用  查看    

2007-07-24 17:56 by 刚刚      
呵呵,确实都很夸张,从我这个评论往上看和往下看(包括我的评论“唯一”词组的前部分),唯一不夸张的就是老赵的随笔内容了,真实可信、实用性高、文采流畅,非常有用哦!
没收了……

#19楼    回复  引用    

2007-07-24 22:24 by Cat Chen [未注册用户]
原来ASP.NET AJAX的RTM还是那么多bug要人手阅读代码才能处理啊……CTP的时候这样做还是很有乐趣的事情,RTM的话就会让人觉得有点不可靠了。

#20楼 [楼主]   回复  引用  查看    

2007-07-25 00:01 by Jeffrey Zhao      
@Cat Chen
我在想是不是随3.5的发布会修正这一点.

#21楼    回复  引用  查看    

2007-07-25 10:10 by winnerzone      
看完之后再看标题才知道终于是干什么了的.收藏了.

#22楼    回复  引用  查看    

2007-07-25 12:49 by 么么茶      
哎~~.NET确实是问题多多,什么时候老赵能结合篇Asp.NET Ajax + Cache 的文章吗,搞来搞去也搞不妥?

#23楼 [楼主]   回复  引用  查看    

2007-07-25 13:36 by Jeffrey Zhao      
@么么茶
嗯?Asp.NET Ajax + Cache是什么意思?

#24楼    回复  引用  查看    

2007-07-25 16:33 by 4kapple      
Cache 为咔嚓,就是咔嚓一声,脖子断了,问题搞定了.
Asp.NET Ajax + Cache就是说老赵同志写一篇文章就将asp.net这点玩意搞定了!
呵呵~

#25楼    回复  引用    

2007-08-18 02:59 by 孟海86 [未注册用户]
技术是被问题逼出来的……

#26楼    回复  引用    

2007-08-25 11:37 by mengye [未注册用户]
问一个js与webservice或pageMethod方法执行顺序的问题,我有一个js方法:
function checkStorage(proId,isComepage)
{
var rV="0";
PageMethods.storageCheck(proId,getValue)
function getValue(result)
{
rV=result;
}
if(rV=="0")
return true;
else
return confirm(rV);
}
方法的功能是当PageMethods.storageCheck返回的值不是“0”的话就执行return confirm(rV);很显然这段代码不达到预期的效果,在还没有等PageMethods.storageCheck执行完返回值就已经执行了下面的代码,结果rV还是="0",不用说你也知道我的问题了,因为checkStorage是通过客户端的按钮触发的,无法通过为AJAX 请求添加客户端结束事件的方法解决执行顺序的问题,@Jeffrey Zhao 有没有解决等执行完pageMethod方法才执行js脚本的办法,谢谢了!

#27楼 [楼主]   回复  引用  查看    

2007-08-25 20:06 by Jeffrey Zhao      
@mengye
没有。使用Callback的异步调用有其特殊的编程方式,因为是做不到阻塞的。

#28楼    回复  引用    

2007-08-27 09:41 by mengye [未注册用户]
郁闷了,看来我只能改程序了,谢谢@Jeffrey Zhao

#29楼    回复  引用    

2007-08-31 14:49 by horsefaced [未注册用户]
在实际中有遇到这种事,就是调用httpRequest的abort方法,会在某些机子上发出没有权限这种错误,不知道博主是否有遇到过。

#30楼    回复  引用    

2007-09-10 16:43 by Halie [未注册用户]
就算不认识,也得顶一下.

#31楼    回复  引用    

2007-12-10 17:34 by xxxxxxxx [未注册用户]
唉,看不懂,,

#32楼    回复  引用  查看    

2007-12-29 10:41 by Allan Chan      
看不太懂,请问下如何得到WebService的代理代码啊?能说详细点吗?谢谢老赵。

#33楼    回复  引用    

2008-01-25 09:25 by Arron [未注册用户]
我有个问题想请教一下,在asp.net ajax调用web service过程中,如何让javascript对象以xml格式传输到服务端,因为我发现默认是使用json格式

#34楼 [楼主]   回复  引用  查看    

2008-01-25 10:49 by Jeffrey Zhao      
@Arron
如果客户端要用XML传到服务器端似乎没有什么好办法。
建议WebMethod的参数用String,然后再服务器端转成XML。

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      


相关链接: