2. ASP.NET客户端回调 ASP.NET客户端回调(ASP.NET Client Callback)是微软在.NET环境下为开发人员提供的一种异步通讯方式,开发人员可以通过接口ICallbackEventHandler来实现客户端页面和服务器之间的异步通讯。注:在某些场合“ASP.NET客户端回调”也被称为“ASP.NET脚本回调(ASP.NET script callbacks)” 通过XmlHttpRequest进行异步通讯时要在客户端通过JavaScript声明一个异步通讯请求对象,这个对象和浏览器内核有关,例如在IE下面是ActiveXObject("Msxml2.XMLHTTP")。而通过ICallbackEventHandler来实现异步通讯时,则要在服务器端的页面代码文件中,要让页面实现ICallbackEventHandler接口,只要在页面的继承类中加入ICallbackEventHandler类即可。 服务器端代码示例: 服务器端代码示例
客户端代码示例: 客户端代码示例
在页面的继承类中加入ICallbackEventHandler类之后,那么页面中就有两个函数可以直接使用了:public void RaiseCallbackEvent(string eventArgument)和public string GetCallbackResult()。 RaiseCallbackEvent是服务器端接收客户端数据的函数,其参数eventArgument就是数据接口,用来接收客户端在请求时向服务器端发送的数据(目前为止,笔者所了解到的,这种数据格式好像仅仅限于字符串)。GetCallbackResult则返回数据,这个数据直接返回给客户端。这两个函数就是服务器端的数据通讯接口。 服务器端的clientscript = Page.ClientScript.GetCallbackEventReference(this, "arg", "AjaxCallBackComplete", null);语句则定义用于生成客户端脚本。通过查看MSDN可以知道,第二个参数"arg"指客户端要发送的JavaScript字符串变量,这个变量在服务器端由RaiseCallbackEvent(string eventArgument)的eventArgument承接,第三个参数是客户端在服务器端完成回调后接收服务器端发来的数据并进行处理的JavaScrpipt函数。 回调的流程如下: 1.用户点击页面链接触发JS函数doCallBack 2.doCallBack准备好数据放于arg变量中,并调用由服务器端生成的客户端脚本<%= clientscript %> 3.服务器端RaiseCallbackEvent收到数据并调用相关服务器端函数进行处理并赋值给一个全局字符串变量 4.由GetCallbackResult函数将服务器准备好的字符串数据返回到客户端 5.客户端由GetCallbackEventReference()设置的JS函数接收来自服务器端返回的字符串数据,然后再对数据进行处理并操作页面元素对数据进行显示等等。 以上便是ASP.NET客户端回调的完整过程。开发人员只需要让页面继承一个ICallbackEventHandler类,然后找到数据接口和函数接口就可以轻松实现异步通讯了。此方法是就是笔者今年做一个数据查询系统所选用的异步通讯方法,因为此方法流程比较清晰,而且代码量对比第一种利用XmlHttpRequest的方法也小了很多。 3. ASP.NET AJAX—ScriptManager注册WebServices方法 ASP.NET AJAX是最新的微软AJAX解决方案。需要在ASP页面中拖入一个ASP.NET AJAX ScriptManager控件作为页面的第一个控件。 通过ScriptManager控件注册WebServices方法可以实现在客户端对服务器端函数进行调用并生成客户端代码,调用格式和客户端回调类似。 具体实现步骤如下: 3.1新建Web服务,会在根目录下生成一个” SimpleService.asmx”文件 此文件可以将声明和实现的代码分别放在两个文件内,只需要进行定位指向即可,然后就能够调用此Web服务类了
当然也可以将声明和实现放在同一个文件夹内,和demo.aspx与demo.aspx.cs的关系一样,但一般建议分开放,使项目文件层次更加清晰(虽然一个”*.asmx”文件里面只能有一个WebService声明指令)。本文就以代码分开存放的结构来讲解。 3.2为Web服务建立实现的” SimpleService.cs”文件 此文件就是WebService在服务器端的数据处理函数。下有一例:
拥有[WebMethod]声明的函数HelloWorld(),其参数name接收来自客户端传来的参数,然后返回一个字符串到客户端。 3.3向” Ajax_net_Callback.aspx”文件中拖入ScriptManager控件 主要演示代码如下:
在ScriptManager内部注册Web服务: <asp:ServiceReference Path="~/SimpleService.asmx" /> 这样,本来是一个服务器端由C#语言写的类可以直接在客户端通过JS以一定的方式调用了。 3.4然后用户就可以在客户端直接调用服务器端的WebService的实现类了。 在按钮点击事件所触发的函数中加入对Web服务的调用:
第一个参数是客户端要传递的JS字符串,第二个是设定客户端接收来自服务器上的Web服务返回数据的JS函数,第三个是响应超时的JS函数,第四个是通讯出错的JS函数。客户端JS函数OnComplate(arg)的参数arg就是用来承接来自Web服务的数据的。位于服务器端的WebService一般返回string型的字符串。而用户完全可以把服务器端的轻量级别的数据以XML或者JSON的格式编码成字符串,然后一并传送(这将是下一节要介绍的内容)。 关于WebService的研究也是一个很大的课题,WebService的功能很强大,除了能返回文本字符串外还能直接返回DataTable,甚至文件流。目前笔者还没有仔细研究过,不过,返回字符串的功能已经足够一般的数据库编程了。 对于Web服务,笔者是比较看好的,只因为笔者已经在目前做的系统中大量用了“客户端回调”的方法来实现异步通讯了,所以就没有再去更改用此方法,但是调用Web服务的编程模式的好处显而易见,在程序设计流程上比利用ICallbackEventHandler要容易得多,而且程序设计时候,完全可以按照不同的数据请求,建立不同的Web服务,放在不同的文件夹下,更容易实现模块化程序设计,当然这只是笔者深刻体会到的,Web服务还有很多其它优点,开发人员可以到网上去自己查找。 4.其它局部刷新方法 以前在学习AJAX时,自己到网上找资料,好像还有种通过引用Ajax.dll或者AjaxPro.dll然后可以实现客户端调用服务器器端的函数的方法。不过,后来觉得相关资料太少,可能也不是主流吧,所以就没有深入研究下去了,有兴趣的同学们可以去研究下。
二、JavaScript 运行在客户端的程序 JavaScript作为客户端脚本,根据笔者Web应用程序开发的经验来看,在ASP网页开发中扮演的地位完全不亚于C#,可以说应该是等同的,一个运行于客户端一个运行于服务器端。目前笔者对这两种语言的定位就是:JavaScript运行于客户端,负责浏览器上页面的程序设计,C#运行于服务器端,负责响应客户端的请求并计算和处理数据,然后通过网络通讯技术数据的交换将服务器和客户端Web应用程序联系起来成为一个整体。 JavaScript主要处理的事情有: 1.客户端发起异步请求(上一节已经提到) 2.接收来自服务器端异步发来的数据并完成解码(下一章将提到) 3.操作页面元素(基于DOM模型),负责数据在客户端的计算和呈现 总之,JavaScript就像“胶水”一样将异步通讯的各个过程粘合到一起。 关于JavaScript,对于初学者,笔者有几条建议和说明: 1).JavaScript是客户端语言,所以不要指望它有像C#那样智能的编辑环境,像VS2008能够提供语法高亮并提示一些简单的对象成员的编辑器已经就不错了。 2).JavaScript的调试方法,可以在你想要设置断点的JS语句前面加上debugger语句,然后将页面用IE打开,在JS程序运行到debugger语句时候,便会有弹出框提示你用VS2008来对JS脚本进行调试,你可以在VS2008的调试环境中观察JS函数的临时变量以及异常状况。 3).JavaScript是解释性语言,所以你在编写客户端代码时候,编辑器不会像提示C#那样智能报错,所以你需要一句一句仔细写,最好写一小段就运行一次,否则你一次性写入大量代码,最后在运行时出错,你很难找到错误原因的。所以调试器可以帮助你解决逻辑问题,但是语法问题还是要靠自己解决。不过,因为JS是客户端代码,所以网上的JS代码例子资源是相当丰富的,甚至你随便打开一个网页,看到里面有好的JS效果,你都可以察看其源文件看到其JS函数的。而且网上有很多开源的已经封装好的JS框架,方便你在大规模写客户端代码时引用,这些都需要开发人员去自己学习了。 4).和其它语言一样,JavaScript的学习也是边用边学,不需要你一开始就要有很好地基础,遇到问题就可以到网上搜索相关解答,资源相当丰富。 总述:看本文有前提就是要有一定C#和JavaScript基础,所以关于语言具体的学习内容,不是本文的重点,所以还请读者自己查询相关资料。
三、XML通讯消息的编码 通过对通讯过程的介绍可以知道传输的数据一般是字符串格式,如果已经将前面的内容掌握了,你就可以对任意简单字符串进行传递了,如果要传递比较复杂的数据集合就需要在此字符串的编码上大做文章了,这就是AJAX中的XML的内容了。有一个概念希望大家能够明白――字符串可以是很长串的数据。不要觉得很不可思议,要知道整个网页的页面都是靠超文本来传输的,一般进行的AJAX通讯的数据不会太大的,都可以用一个字符串进行承载,比如笔者就用一个字符串传送过50K的数据,而显然字符串承载数据的能力远不止如此。对数据编码掌握后,就可以完全异步通讯数据的规模“从一到万”的质变。 下面将介绍几种常用的数据编码技术,用户可以根据情况任意选择一种了解和应用。 3.1 用户自定义分隔符编码(微量级别) 简单的URL后面的传递: 比如:string strEncode=”a=10&b=20&c=30” 这样以特殊符号作为分隔符的编码方法比较适用于结构单一的数据集合,数据在客户端和服务器端的编码和解码也是最简单的,编码只需要字符串相加即可,解码只需要用split()函数(C#和JS两种语言都有此函数)按照编码的分隔符规则进行分离并提取出有用信息即可。 总述:此方法好处是数据编码和解码很容易,坏处也显而易见,字符串所表示的数据集合结构层次不明,当数据集合稍微有点大的时候,字符串的可读性将变得很差。所以本方法只适合于传递的数据量比较少层次比较少的微量级别,比如一般传递不多于5组的层次单一的数据,如上例所示,但即使如此,也可以满足一般的开发者的需求了。 下面再讲的JSON编码是对于轻量级别(比微量级别要复杂一些)的数据的一种编码方式, 3.2 JSON编码技术(轻量级别) 关于JSON的介绍,网上有这么一段话:JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式易于人阅读和编写同时也易于机器解析和生成。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)这些特性使JSON成为理想的数据交换语言。 关于JSON编码更详细的介绍可以到网上查找相关文档,或者直接访问其官方网站json.org。 在做以下步骤之前,请到这个地址下载json.js和JSON.CS http://www.json.org/json.js 作为客户端JSON编码和解码的库文件 http://www.json.org 找到JSON for .NET的链接。作为服务器端JSON编码和解码的库文件。 3.2.1 服务器端JSON编码和解码 用从json.org网页中下载的“JSON.CS“文件,然后在服务器端中引用引文件,就可以在写C#函数的时候调用里面的函数了。具体如何详细应用细节,用户可以自己去试验。笔者在此只作简要介绍,笔者对”JSON.CS“文件进行了查看,发现里面函数虽然众多,但是直接给外部调用的只有两个:
调用方法示例:
即一个是编码函数一个是解码函数:编码函数将服务器端的object对象转换成字符串对象,然后传递到客户端;解码函数将从服务器端接收到的string对象转换成object对象供服务器提取数据。其余的函数都是供这两个函数调用的。 需要说明的是,上面所说的string类型的数据不是一般的任意字符串,而是有一些特别分隔符组成的“JSON字符串“,只有这样格式良好的string字符串才能够被此文件中的函数进行解码,而编码的作用也就是将object数据类型编码成这样的格式良好的“JSON字符串“,正因为遵守了这样的规则才使得JSON编码能够跨语言传递数据了。 对于服务器端的object对象,通过查看“JSON.CS“源文件,发现它的编码和解码主要基于一种Hashtable或者ArrayList的数据类型,因此用户在服务器端对数据编码的时候,首先要转换成此结构的数据类型。然后再直接调用”JSON.CS“中的编码将Hashtable或者ArrayList的数据转换成JSON格式的string类型字符串。解码也是一样的,当服务器收到来自客户端的JSON格式的string类型字符串的时候,先调用”JSON.CS“中的解码函数,然后再用Hashtable或者ArrayList类型的中间变量来承接这些数据,然后就可以提取出其中有用的数据了。 3.2.2客户端JSON编码和解码 从json.org网页中下载的”json.js”文件,然后在客户端引用此文件,就可以在写JS函数的时候调用里面的函数了。和服务器端的”JSON.CS”相对应的,它里面虽然代码众多,但是供外界调用的也只有两个函数――一个编码函数一个解码函数:
调用方法示例:
json是JavaScript里面的一种数据格式,其地位相当于C语言中的结构体一样,是一个数据集合,用户可以通过“结构体“的点运算符直接对里面的数据进行提取和引用。 (责任编辑:admin) |