网管联盟 | 网管论坛 | 网管u家 | 网管博客 | 网管软件 | 网管求职 | 小游戏 | 网管搜索 | 网管原创 | 网管聚合 | 网管读摘 | 网管焦点 | 世界素材 | 会员投稿 | 会员中心 
中国网管联盟
Windows Linux Cisco 网络技术 数据库 黑客攻防 DotNet Java PHP 认证 新闻资讯 服务器 存储资讯 网络设备 网管学堂 技术专题 焦点 网吧频道
 当前位置: > bitsCN.com > DotNet > XML&Web > 客户端访问Web Service方法的一个细节  

客户端访问Web Service方法的一个细节

2007-07-26  作者:bitsCN整理  来源:中国网管联盟  点评 投稿 收藏

  

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

网管u家u.bitsCN.com

  首先假设有如下的Web Service方法定义(DemoService.asmx): 网管u家u.bitsCN.com


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

中国网管联盟bitsCN.com

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

网管bitscn_com

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);
... 

网管联盟bitsCN_com

网管下载dl.bitscn.com

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

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());
} 

网管网www_bitscn_com

网管u家u.bitscn@com

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

中国网管联盟bitsCN.com

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;
} 中国网管论坛bbs.bitsCN.com 

中国网管联盟bitsCN.com

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

var request = DemoService.DemoMethod(onComplete); 中国网管论坛bbs.bitsCN.com 

网管网www_bitscn_com

  然后在必要时: 网管论坛bbs_bitsCN_com

request.abort(); 网管下载dl.bitscn.com 

网管联盟bitsCN@com

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

DemoService._staticInstance = new DemoService();
...
DemoService.DemoMethod = function(onSuccess,onFailed,userContext)
{
    DemoService._staticInstance.DemoMethod(onSuccess,onFailed,userContext);
} 
网管论坛bbs_bitsCN_com

网管联盟bitsCN_com

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

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

网管bitscn_com

var request = DemoService._staticInstance.DemoMethod(onComplete); 
网管u家u.bitsCN.com

网管u家u.bitscn@com

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

网管网www.bitscn.com

var demoService = new DemoService();
var request = demoService.DemoMethod(onComplete); 中国网管联盟bitsCN.com 

网管bitscn_com

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

网管u家u.bitsCN.com


TAGs   一个   细节   方法   访问   客户端   request   对象   userContext      
 上一篇:如何让WebServer返回指的定XML内容   下一篇:关于Debug和Release之本质区别的讨论
客户端访问Web Service方法的一个细节 评论:
loading.. 评论加载中…
评论:请自觉遵守互联网相关政策法规,评论不得超过250字。

验证码: 注册用户
本类热门排行:
最新推荐文章:
网管论坛交流: