Hello World
Spiga

深入Atlas系列:Web Sevices Access in Atlas(1) - 客户端支持

2006-10-10 02:43 by 老赵, 3891 visits
  注意:部分内容已经过期,请结合《深入Atlas系列:Web Sevices Access in Atlas(7) - RTM中的客户端支持》阅读此文。

Atlas提供了强大而灵活的服务器端Web Services访问能力。这对于客户端AJAX开发提供了绝好的条件,这几乎也是任何AJAX框架必备的功能。因为只要有了它,就能轻松地以AJAX方式与服务器端进行交互,而其他多样的页面操作自然可以由开发人员尽情开发。对于部分喜欢自己动手的开发人员来说,这甚至是他们仅仅需要的支持。

从这篇文章开始,我会从实现角度剖析Atlas对于Web Services的支持,希望能够帮助大家更深入地理解,更灵活地使用Atlas提供的这一功能。

在Atlas中,对于Web Services的访问,其实都是通过Sys.Net.ServiceMethod类来实现的。我们先通过UML来看一下Sys.Net.ServiceMethod以及其其他一些类的关系。

Sys.Net.WebMethod类是Sys.Net.ServiceMethod和Sys.Net.PageMethod的父类。后者用于访问写于页面中使用WebMethodAttribute标注的方法,不在这篇文章的讨论范围内。Sys.Net.WebMethod内定义了五个抽象函数:get_methodName、addHeaders、get_url、get_body和get_appUrl,其作用应该相当地显而易见。而继承Sys.Net.WebMethod的类,例如Sys.Net.ServiceMethod,则提供了这五个抽象函数的实现。

Sys.Net.WebMethod类有一个非常有趣的函数“invoke”。从UML图中会发现,它居然提供了一个Javascript中没有的功能:“函数重载(overload)”!至于它是如何实现,该如何使用,稍后将结合代码进行详细介绍。

那么就进入代码分析阶段,先从Sys.Net.WebMethod的结构看起,从一个Atlas类的大致结构可以看出该类的成员定义和“构造函数”的实现。
Sys.Net.WebMethod结构

可以见到五个抽象函数定义,在this._invoke函数是真正产生请求的地方,里面还有数个用于引发事件的方法。整个类的结构非常简单。

接下来我们来仔细分析一下this.invoke函数。
this.invoke函数分析

可以看到,这就是就是this.invoke“函数重载(overload)”的实现方式。到底是故意如此设计还是在后续开发时为了兼容,可能就不得而知了。不过也就是说,我们现在有中参数传递可以使用。

第一种是:
this.invoke第一种调用方式

第二种是:
this.invoke第二种调用方式

关于参数的含义,请参照this._invoke函数的分析。

接下来分析this._invoke的代码,这才是真正工作的代码。
this._invoke函数分析

可以看出,Sys.Net.WebMethod是使用Sys.Net.WebReqeust来发出AJAX请求的。在Atlas应用中如果需要使用AJAX请求的话,应该全部使用Sys.Net.WebRequest,这个类不仅对于XMLHttpRequest进行了良好的封装,另外它使用了Sys.Net._WebRequestManager对于所有请求进行了全局地控制,使用了浏览器和HTTP协议的特性,提高了请求的效率。这一点几乎是微软介绍Atlas时都会着重强调的一点。

在创建了Sys.Net.WebRequest对象后,并不是将用户传入的那些回调函数直接注册给它的事件,而是使用了Sys.Net.WebMethod里的onXXXX,进行了进一步的处理,代码如下:
onXXX函数分析

在onComplete方法中,会查看status code。在HTTP 1.x中,2xx代表了Success(关于完整Status Code的描述,请参考http://www.w3.org/Protocols/HTTP/HTRESP.html)。由此可以得知该如何调用用户提供的回调函数。在调用回调函数时会将用户提供的userContext作为参数传入,这种做法在异步调用中被经常使用,例如.NET Framework中Delegate的异步调用。

至此,Sys.Net.WebMethod就被解释完了,并不复杂,甚至我觉得我的解释有些累赘。不过它提供的方法非常重要,是客户端访问服务器端函数的核心(客户端方面)。而调用Web Services,则需要Sys.Net.ServiceMethod这个Sys.Net.WebMethod的子类来提供那五个抽象函数的具体实现,分析如下:
Sys.Net.ServiceMethod代码分析

对于传入参数url和appUrl,可能需要重新解释一下。如果url传入的是相对路径,则appUrl可以为null。

为了有更深的理解,我们来看一个例子:

ws.asmx代码:
ws.asmx文件代码

HelloWorld函数接受一个整数作为参数,返回一个数组。第一个元素为一个字符串,第二个元素为服务器当前时间。

Default.aspx文件代码:
Default.aspx文件代码

在这里使用的是invoke函数的第二种调用方法,传入一个随机数作为参数,并将信息显示在页面上。效果如下:



我们打开Fiddler,看看具体的请求如何,请注意红色框出的地方:

Request:


Request Body:


Response Body:



是不是和我们预料的完全相同?有了JSON,我们可以非常方便地构造和表示一个客户端对象,Atlas在客户端和服务器端都提供了非常强大的JSON Serializer。这些方法可以应用在任何需要场合,即使脱离了Atlas。

到现在为止,已经将Atlas以AJAX方式调用Web Services的客户端基础代码分析完了。但是这其实还远远不够,有了客户端代码,至少还需要服务器端的支持。那么在服务器端Atlas又是如何提供以AJAX方式调用Web Services方法的功能呢?

我们将在下一篇文章中讨论这个问题。


点击这里查看范例。
点击这里下载范例。

Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

26 条回复

  1. 老赵
    admin
    链接

    老赵 2006-10-10 02:45:00

    写这样一片东西,居然花了我整整两倍的预计时间……

  2. 兰亭
    *.*.*.*
    链接

    兰亭 2006-10-10 07:00:00

    先收藏……

  3. 菌哥
    *.*.*.*
    链接

    菌哥 2006-10-10 07:18:00

    老赵辛苦了!

  4. TerryLee
    *.*.*.*
    链接

    TerryLee 2006-10-10 08:18:00

    老赵终于开始了深入Atlas系列,呵呵:-)

  5. henry
    *.*.*.*
    链接

    henry 2006-10-10 09:02:00

    不知道对于复杂对象类型的参数和返值是否方便?
    期待后继!

  6. gooddream[未注册用户]
    *.*.*.*
    链接

    gooddream[未注册用户] 2006-10-10 10:13:00

    辛苦了,
    好东西,先收藏再研究!

  7. 补丁[匿名][未注册用户]
    *.*.*.*
    链接

    补丁[匿名][未注册用户] 2006-10-10 10:14:00

    问个问题,如果用altas访问webservice的方式开发web应用,是否意味着,其他网站能够通过访问我的webservice,得到同样的服务?
    如何限制只有我自己开发的ajax程序能够使用这个webservice呢?

  8. aysun168[未注册用户]
    *.*.*.*
    链接

    aysun168[未注册用户] 2006-10-10 11:13:00

    对于OPERA支持的还不够好啊!

  9. 老夫子系
    *.*.*.*
    链接

    老夫子系 2006-10-10 11:35:00

    好东西,先收藏。

  10. 老赵
    admin
    链接

    老赵 2006-10-10 12:51:00

    多谢大家支持。:)

  11. 老赵
    admin
    链接

    老赵 2006-10-10 12:55:00

    @henry
    它对于参数或返回值的复杂类型支持相当于普通的Web Services,因此是足够强大的。

  12. 老赵
    admin
    链接

    老赵 2006-10-10 13:01:00

    @补丁[匿名]
    完全可以,虽然无法使用Windows Authentication(毕竟是AJAX,Windows Authentication要求系统级别的验证信息发送)。
    最方便的方式就是使用ASP.NET的Forms Authentication,由于XMLHttpRequest和普通浏览器POST/GET一样,在Request时会自动地加上Cookie信息,因此对于Forms Authentication是提供了天然的支持,我们要做的只是处理好异常即可。:)

  13. 老赵
    admin
    链接

    老赵 2006-10-10 13:04:00

    @aysun168
    的确,在http://ajax.asp.net里也能够看句Atlas描述
    Works on a wide variety of browsers and platforms, with no client code deployment, including the latest versions of:
    Internet Explorer
    Firefox
    Mozilla
    Safari (limited functionality—full functionality provided in a future release)

    可以看出Atlas对于Opera的支持的确不好。大概是Opera的Compact Layer比较难写吧,我对Opera不太了解,不敢多说。:)

  14. henry
    *.*.*.*
    链接

    henry 2006-10-10 13:07:00

    [Serializable]
    public class User
    {
    public string Name;
    public string Remark;
    }
    [Serializable]
    public class Company
    {
    public string Name;
    public User[] Items;
    }
    对于Company类型的参数和返回值,不知道Atlas是如何使用的;毕竟这种情况很普通,因此想了解这方面的东西。

  15. 老赵
    admin
    链接

    老赵 2006-10-10 13:39:00

    @henry
    使用JSON,能够很好的处理这种复杂类型,但是其实开发人员其实并不需要了解JSON。下一篇我会提到这一点。:)

  16. Evila[未注册用户]
    *.*.*.*
    链接

    Evila[未注册用户] 2006-10-12 17:12:00

    好东西!不收藏,在线研究

  17. 老赵
    admin
    链接

    老赵 2006-10-12 17:17:00

    @Evila
    这个好。多谢支持。:)

  18. Evila[未注册用户]
    *.*.*.*
    链接

    Evila[未注册用户] 2006-10-12 18:17:00

    我一直在呢,看明白啦,刚接触NET,
    感谢老赵,一路陪伴我们~~!

  19. 老赵
    admin
    链接

    老赵 2006-10-12 19:30:00

    @Evila
    我想在园子里应该出现点深入Atlas的东西了,官方文档上的内容都讲得差不多了。:)

  20. 蛙蛙池塘
    *.*.*.*
    链接

    蛙蛙池塘 2006-12-03 11:18:00

    RTM新还是BETA2新呀?
    Sys.Net.ServiceMethod是c#还是js呀,你怎么导出的类图呀?
    js里的继承怎么实现的,还有父类呀?给举个简单的例子,或者给个链接地址。
    this.addHeaders = Function.abstractMethod;这句的Fuction是js自身的吗?
    this._invoke = function(){}里面套着那几个函数是干啥的呀,为啥函数套函数呀?
    debug.trace把调试信息输出到哪儿了?
    Fiddler在哪儿呢?
    JSON是JS的基本功能吗?不受浏览器限制是把?

  21. 老赵
    admin
    链接

    老赵 2006-12-03 12:44:00

    @蛙蛙池塘
    Beta2新,Sys.Net.ServiceMethod是客户端的类库,类图是自己画的。JS里继承的话是“模拟出来的”,您可以在官方网站(http://ajax.asp.net)里看到。Function是JS的对象。套的函数就是“Inner Method”,debug.trace把信息输出在页面上。Fiddler可以在“http://fiddlertool.com”上下载,JSON是JS天生支持的。
    // 我觉得您应该先补充一下JS的基础……:)

  22. 蛙蛙池塘
    *.*.*.*
    链接

    蛙蛙池塘 2006-12-03 13:50:00

    给推荐一本js书呀,我js半吊子,呵呵。应该深入学学。

  23. 老赵
    admin
    链接

    老赵 2006-12-03 14:58:00

    @蛙蛙池塘
    《Professional JavaScript for Web Developers》,这本不错。:)

  24. 蛙蛙池塘
    *.*.*.*
    链接

    蛙蛙池塘 2006-12-03 22:17:00

    哥,有中文版吗?你这不是难为我吗?

  25. 老赵
    admin
    链接

    老赵 2006-12-03 22:30:00

    @蛙蛙池塘
    市面上已经有人翻译了,你可以找找看。:)

  26. miaojm[未注册用户]
    *.*.*.*
    链接

    miaojm[未注册用户] 2009-03-03 16:53:00

    非常喜欢您的讲座,受益匪浅,谢谢!

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我