第18章AJAX中的Web服务在前面的章节中已经多次介绍到在ASP.NETAJAX中调用Web服务,本章将详细讨论在ASP.NETAJAX框架中Web服务的运行原理以及如何在客户端调用Web服务。18.1概述Web服务是从英文WebServices直接翻译过来的。很多技术人员初次接触Web服务,会认为这是一个新的系统架构和新的编程环境。其实,虽然Web服务是一个新的概念,但它的系统架构,它的实现技术却是完完全全继承已有技术的,绝对不会使现有的应用推倒重来,而是现有应用的面向Internet的一个延伸。Web服务其实就是一种无需购买并部署的组件,这种组件是被一次部署到Internet中,然后到处可用的一种新型组件,所有应用只需要能够连入Internet,就可以使用和集成Web服务。Web服务是基于一套描述软件通信语法和语义的核心标准。XML提供表示数据的通用语法;简单对象访问协议(SOAP)提供数据交换的语义;Web服务描述语言(WSDL)提供描述Web服务功能的机制。其他规范统称为WS-*体系结构,用于定义Web服务发现、事件、附件、安全性、可靠的消息传送、事务和管理方面的功能。简单的说,Web服务就是一种远程访问的标准。它的优点首先是跨平台,HTTP和SOAP等已经是互联网上通用的协议;其次是可以解决防火墙的问题,如果使用DCOM或CORBA来访问Web组建,将会被挡在防火墙外面,而使用SOAP则不会有防火墙的问题。要发展Web服务需要更多的软件厂商来开发Web服务,让基于Web服务的软件服务多起来。以上只是对Web服务进行了简单的介绍,本章不会详细介绍Web服务的内容,本章所要介绍的内容主要是介绍ASP.NETAJAX框架的Web服务运行原理以及如何在客户端调用Web服务。其实在ASP.NETAJAX框架提供了一个异步通信层,它负责服务器端和客户端的异步通信。基于这个异步通信层,使客户端调用Web服务成为可能。18.2异步通信层ASP.NETAJAX异步通信层(asynchronouscommunicationlayer,ACL)使得通过客户端程序调用服务器端的Web服务成为可能。ACL层提供了能够使任何浏览器中的JavaScript函数调用服务器端的Web服务的API。这些API能够使用由浏览器的XMLHTTP对象提供的浏览器异步行为的功能。当前比较流行Web程序架构是典型的三层结构,即:业务层、数据层和表现层,一般会把业务层和数据层放在服务器端,表现层放在客户端,而异步通信层能把服务器端的业务层和数据层与客户端的表现层做明显的划分。这样浏览器能够控制表现层,并提供一个丰富的用户接口,而服务器端则执行业务和数据层的任务。18.2.1异步通信层的特性异步通信层提供了如下的特性:●能够使JavaScript代码执行对服务器的异步调用。●能够调用Web服务提供的方法。●能够调用成为Web服务方法的ASP.NET静态页面方法。●能够配置以启用和禁用ASP.NETAJAX程序来调用Web服务。●支持一系列在浏览器和服务器间传输的数据的序列化,这些序列化格式包括JSON格式、字符串格式和XML格式。●通过为Web服务生成JavaScript委托能够使Web服务通信变得容易。●提供为委托对象所用的执行器的扩展。执行器是一个组件,该组件是客户端请求和网络或其他媒体之间的接口。程序员可以编写自己的执行器,然后把这个执行器插入异步通信层。●能够同中等信任(Mediumtrust)一起使用。18.2.2客户端与服务器端的异步通信模型图18-1描述了客户端与服务器端的通信模型。图18-1客户端与服务器端的异步通信模型图18-1描述了客户端和服务器端的异步通信模型。ASP.NETAJAX的异步通信层包括客户端的异步通信和服务器异步通信。在服务器端业务层和数据层被封装在Web服务中,页面方法也封装在Web服务中,然后通过服务端的异步通信与客户端进行交互。在客户端脚本程序通过服务委托来与服务器端进行通信。而数据的格式一般都是以JSON格式、字符串格式和XML格式来呈现。18.2.3客户端结构客户端异步通信层包含了几个JavaScript组件,图18-2展示了异步通信层的客户端结构。图18-2客户端结构客户端结构主要包括两组:通信组和支持组。通信组包括执行在客户端和服务器端的Web服务的脚本。其实Web请求处理本质上就是一个异步过程,而通信组则建立在浏览器的XmlHttp对象和调度浏览器请求的执行对象之上。通信组包括的脚本主要可以分为两种:Web服务委托类和页面方法委托类。Web服务委托类提供发出Web服务请求的的途径。在ASP.NETAJAX中,异步交互层能够自动地生成客户端脚本委托类,利用这些委托类生成的委托对象可以从客户端脚本中向服务器端发出异步请求。发出异步请求的方式有两种:(1)使用HTTPPOST谓词调用Web服务。POST请求包含浏览器发送到服务器的数据,而这个数据没有大小的限制,因此,当传送的数据大小超过GET请求的限制时可以使用POST请求。客户端会把数据序列化为JSON格式,然后把它作为POST数据发送到服务器。服务器端把JSON格式的数据反序列化为.NET类型并执行实际的Web服务的调用。在回应期间,服务端把返回的数据进行序列化,然后把它们发送到客户端,客户端会把这些序列化的数据反序列化为JavaScript对象。(2)使用HTTPGET谓词。这和POST请求方式相似,不过存在如下差别:●客户端使用查询字符串把参数发送到服务器端。●GET请求只调用被[ScriptMethod(UseHttpGet=true)]配置的Web服务方法。●数据的大小是有限制的,这是因为URL的长度是有限的。页面方法委托类为客户端调用ASP.NET页面中静态方法提供了脚本编程基础,它把ASP.NET页面中静态方法当作Web服务方法来调用。支持组负责处理客户端-服务器通信的委托类和序列化。主要包括如下三个类:●认证委托类,认证委托类是由服务器端的认证服务生成,它使通过JavaScript程序来实现用户登录和退出成为可能,而且无需了解服务器端的处理细节。●Profile委托类,Profile委托类是由服务器端的Profile服务来生成。它使得通过JavaScript访问当前用户的profile信息成为可能,而且不需了解服务器端的处理细节。●JSON序列化类,JSON序列化类用来把JavaScript对象序列化为JSON格式。18.2.4服务端结构服务端的异步通信层同样也包含一些组件,图18-3展示了服务端的异步通信层的结构。图18-3服务端的异步通信层结构服务端的异步通信层包含的组件可分为两组:交互组和支持组。交互组是服务器和客户端之间的高级接口,它包括服务通信组件,它们分别是:●Web服务,在Web服务组件中,服务器执行所有请求处理,并向客户端返回合适的响应。●页面方法,页面方法组件使ASP.NET页面像Web服务一样被客户端所调用。支持组包含处理其它诸如序列化等服务的组件,它们分别是:●JSON序列化,JSON序列化组件能够在.NET类型和JSON格式之间进行序列化和反序列化。●XML序列化。异步通信层支持从Web服务返回XML类型的数据。如果一个Web方法返回一个XmlDocument对象,调用函数会把返回值解析为特定浏览器的XmlDocument对象。●认证服务,认证服务生成认证委过类,并使它在客户端可用。这样就在客户端利用脚本程序来实现用户的登录和退出。●Profile服务,Profile服务生成profile委托类,这个类可以在客户端脚本中被用来获取和设置与当前请求的用户身份像匹配的profile属性。而当匿名认证特性被激活时,Profile服务可以同时为认证用户和匿名用户服务。服务端异步通信层建立在这些组件之上,形成与客户端沟通的能力,而ASP.NETAJAXWeb服务的使用正是基于客户端和服务端的异步通信层才成为可行。18.3向客户端脚本暴露Web服务ASP.NETAJAX提供了调用Web服务的基础,通过为暴露JavaScript委托类可以实现在客户端调用Web服务。可以通过调用与JavaScript委托类相对应的方法来调用服务器上的Web服务方法。ASP.NETAJAX还提供了内置的支持JavaScript调用ASP.NET应用程序服务,例如:Profile服务和Membership认证服务。18.3.1启用JavaScript调用Web服务当安装了ASP.NET2.0AJAXExtensions后,在VS.NET2005中创建一个ASP.NETAJAX网站时自动添加的Web.config文件就会注册ScriptHandlerFactory的HTTP处理器。示例代码如下:system.webhttpHandlersremoveverb=*path=*.asmx/addverb=*path=*.asmxvalidate=falsetype=System.Web.Script.Services.ScriptHandlerFactory,System.Web.Extensions,Version=1.0.61025.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35/addverb=*path=*_AppService.axdvalidate=falsetype=System.Web.Script.Services.ScriptHandlerFactory,System.Web.Extensions,Version=1.0.61025.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35/addverb=GET,HEADpath=ScriptResource.axdtype=System.Web.Handlers.ScriptResourceHandler,System.Web.Extensions,Version=1.0.61025.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35validate=false//httpHandlerssystem.web为了启用JavaScript能够调用.asmxWeb服务,首先需要在页面上添加ScriptManager控件,然后在ScriptManager控件的asp:ServiceReference子元素中设置属性path为要调用的Web服务的地址。这样的设置指示ASP.NETAJAX框架生成一个JavaScript委托类来调用指定的Web服务。示例代码如下:这段代码启用了JavaScript来调用名为SimpleWebService.asmx的Web服务。asp:ScriptManagerrunat=serverID=scriptManagerServicesasp:ServiceReferencepath=~/WebServices/SimpleWebService.asmx//Services/asp:ScriptManager当包含asp:ScriptManager元素的页面被构建时,就会为创建SimpleWebService.asmxWeb服务一个JavaScript委托类。这个委托类具有与SimpleWebService.asmxWeb服务的每个方法相对应的方法。页面还会包含与用于Web服务方法输入参数或返回值的服务端数据类型相对应的JavaScript委托类。这样可以起用JavaScript来对这些参数或返回值进行初始化。在asp:ServiceReference标记中的InlineScript属性指出生成JavaScript委托类的脚本如何包含在页面中。这个设置指出脚本是否以脚本块的形式被包含在页面内还是作为单独资源来加载。InlineScript属性的设置如下:●