在这里我将试图考察一下目前.NET平台的下的AJAX框架,我也试图从中总结出来一种方法,使得你可以在众多基于.NET平台的AJAX框架和工具包中 找到你所合适的一种,同时也希望你在考察、预研和使用这些流行的这些AJAX-NET 的框架时,做得理性和有的放矢。
我想,文章的方法会给目 前使用AJAX的.NET用户带来帮助,从而提高你在.NET平台下使用AJAX的体验。为什么这么说,因为最近我的一个客户(应该是一些客户)的研发主 管对我说,我们对Atlas 非常兴趣,想了解更多一些相关的内容和如何开始看待Atlas,因为下个月会来一个Atlas的专家和我们交流。因为我知道这个主管手上掌握着一个 AJAX架构的业务应用,目前在考虑从.NET v1.1迁移到.NET v2.0,Atlas能在怎样的程度上帮忙他或他的Team?我没有说太多,因为心里我有些吃惊,目前的他们的架构应用Atlas 可能并不是一个明智的选择,当然这个担心基于我目前对Atlas的理解。
我列举和讨论的AJAX-NET的框架和工具包括 Atlas(Jan CTP), Anthem.NET, MagicAJAX.NET , AJAX.NET Professional 和wwHoverPanel Control,这基本都是我关注的.NET平台的下的AJAX 的一些框架和实现。 基本上也都是我的这篇文章中列举的,另外一个原因是因为他们基本上都是开源的,这个非常重要,因为没有源代码,我们将不知道究竟发生了什么。另外我无意于 使之成为像Daniel Zeiss作的这个比较报告。
首先,开门见山的说明我的观点。
对于开源或现有的 AJAX-NET技术或框架的选用必须针对你目前应用的架构来选取和考虑,如果你目前的架构是"似AJAX"的,那么你在选择现在所有流行的AJAX- NET的技术的时候都必须非常小心;而如果你目前的应用是使用传统的ASP.NET的应用架构(或准备用ASP.NET v2.0开始创建新的应用),那么目前流行的AJAX-NET的框架和技术都是普遍适合的,关键你要在合适的时机选择合适的某个框架或实现。
在我的眼中,目前流行的AJAX-NET的框架或实现都是Add-in (Plug-in)的模式的,也就是说这些框架对于所有后一种即使用传统的ASP.NET的应用架构(或准备用ASP.NET v2.0开始创建新的应用)是Awared的也就是非常有利和方便的。但对于"似AJAX"的架构来说,情况有所不同,需要你从另外的角度来衡量,有选择 的使用。
那什么是"似AJAX" 的架构呢,这就是说,你的应用程序是在AJAX概念提出之前就创建的。从客户端和服务器端的交互分析来说,你的客户端有大量的Javascript 代码接受XML数据,进行对象的序列化,然后使用Javascript配合其它的HTML技术展现这些对象和数据,也可能你还有一堆HTC或其它的 Javascript的HTML表现层控件。你的服务器端是一个Facade(或者是Adapter,Observer)模式的(Handler)控制 器,接收客户端Javascript的XML请求数据后,然后解析XML,然后调用相应的某个服务或业务组件,再将结果以XML的形式返回给客户端 Javascript ,客户端的Javascript接收之后,再进行处理和显示,因为可以使用HTML的DOM 和CSS,所有页面的展现是动态的。
这样客户端是中描述的Script-centric architecture 或Data-centric interactions 的方式。而且这种方式和Jesse James Garrett列举的AJAX 是最类似的,只不过那时你或我不知道这个可以叫AJAX,只不过是现在的人误解了AJAX,AJAX成了一种技术,一种特性,而首先不是一种某种架构下 Web 应用了。
而且目前流行的AJAX-NET的框架基本上都没有实现双向序列化,因为实现一个TextBox的自动完成客户端 只用接收数据就行了,根本不用传回数据/对象到服务器端,同样做一个AJAX的状态进度条也不用,但这些都是AJAX啊,我们衡量的标准是异步的、页面没 有刷新。
很抱歉,我用了这么字才解释完我的观点。最后可以这么说,如果你的应用已经是AJAX架构的,那么你需要仔细选择使用目前 的AJAX-NET框架,确保它也提供双向序列化功能,兼容你原来的应用和架构。如果你的应用不是AJAX架构的,那么你可以依据一些条件来选择AJAX -NET框架。
然后我们回到文章的开始,来看一些流行的AJAX-NET框架MagicAJAX.NET
这是目前框架中版本号最小的一个AJAX-NET实现,许多人很喜欢它,甚至一见如故,但真的看过它的代码之后,我有些担忧。
MagicAJAX.NET基于这样一种策略,即__doPostBack 会提及整个的ASP.NET页面,这样会导致页面刷新,所以MagicAJAX.NET使用AJAXCbo.DoPostCallBack 做局部的提交,而每个AJAXPanel 中的内容则对应客户端即时的HTML内容,因为在MagicAJAX.NET中,客户端只用执行eval(responseText) 服务器端Rendered返回的HTML就可以了(很被动)。
由于DoPostCallBack 会提交ViewState 以及AJAXPanelx$RBS_Store,几乎是用XMLHttpRequest 模拟一个正常的提交,所以服务器端可以创建页面的实例也可以根据ViewState 恢复所有的控件状态,同样AJAXPanel 以及AJAXControl 也都会实例化,然后接收客户端传来的_EventTarget, _EventArgument 走正常的ASP.NET控件的处理过程,等控件Rendered之后,最终的HTML输出被传回客户端,然后被客户端的eval 显示出来。
整个过程非常巧妙,这几乎是ASP.NET __doPostBack 的"Hook ASP.NET"版和加强版本。而HttpModel 主要是为了解决Session和交叉提交,进行客户端Javascript的整理和注入,当然也是这里接收客户端的请求,在 Application_EndRequest中返回结果。剩下的代码都是处理控件在VS Web Design中的设计时支持。AJAXCallObject.js 和WebParts.js 每次都要传到客户端。
MagicAJAX.NET 的一些不足和想法:
如果是基于ASP.NET 提供的控件和开发,那么MagicAJAX.NET 是非常有效的,很好的解决了Session和跨页面状态的问题。而且客户端的操作和工作基本可以忽略,MagicAJAX.NET设计贴近最近的 ASP.NET的版本,目前不提供调用客户端直接调用页面的方法。但随着其发展,优势可能渐少,因为Atlas 最新的版本提供类似的UpdatePanel 控件。
AJAX.NET Professional
我没有看过AJAX.NET Professional 的源代码,但从例子中看得其支持调用页面的某个方法,以及返回对象,DataSet,DataTable的数据,我认为AJAX.NET Professional 的实现和Anthem.NET 原理是一样的,虽然AJAX.NET Professional 使用了HTTP Model,这个只是和Anthem.NET 一样,最终处理结果的返回处理上稍有不同不同。比较起来,AJAX.NET Professional 没有重新继承所有常用的ASP.NET控件实现部分提交的功能,所以可能AJAX.NET Professional 比较强项的是调用页面上的某个方法,并在客户端获得结果的数据,这个已经够实现大部分的AJAX的功能了。
从这个层面上看,我认为 AJAX.NET Professional 是相对笨重和复杂了。Anthem.NET不使用HTTP Model,提供控件基本的局部提交,也提供数据层面的客户端方法调用。AJAX.NET Professional 的源代码似乎总是不想共享 ,这也是我不喜欢它的另外一个原因。
无论如何,大家都没有提供两路的数据交换,即客户端可以获得服务器端的方法并获得结果和数据,但是目前都支持将这些对象/数据修改之后返回给服务器端。
Anthem.NET 的一些不足和想法:
wwHoverPanel AJAX Control for ASP.NET 这也是一个ASP.NET的控件,但是提供了客户端回调(高级回调)、客户端调用页面方法,以及双向两路的序列化功能。
wwHoverPanel 吸取了MagicAJAX.NET 和 Anthem.NET的优点,同时又结合了ASP.NET的客户端回调功能,是一个轻量级的AJAX组件。
看待wwHoverPanel 最大的两个特性中的一个是用很简单的方式实现了一个HoverPanel Behavior,这个实现比目前Atalas的Behavior 要简单,作者Rick Strahl 也强调这个主要是结合他具体的应用,比如这里提供了一个小的HTML板,可以显示获得的结果信息。
wwHoverPanel 也提供一个局部回调的方法,但是这点的实现上和MagicAJAX.NET 以及 Anthem.NET完全不同,它是使用一个StartCallback的Javascript来组合查询字符串提交并且使用XMLHTTP发请求到服务 器的某个页面(由ServerUrl 属性指定),之后这个页面将结果以Response.Write()的原生HTML内容返回。这个和ASP.NET的回调方法非常类似,而且还支持将请求 发到本页之外的ASP.NET并获得结果,所以它增强了原来ASP.NET的客户端回调的方法,即支持其它页面的回调。可以说,这是一种基于URL的客户 端回调。
wwHoverPanel 提供的第二个功能是,客户端可以调用服务器端中的某个页面的方法(这些方法以[CallbackMethod]进行标识),这种情况下,你要设置 EventHandlerMode="CallPageMethod" ,然后使用wwHoverPanel.服务器方法名(参数,参数,...,回调处理函数)的方式进行调用。这个其实使用的是一个Javascript的 CallMethod 方法,调用服务器端的请求。Javascript 的HandleCallback 则用来处理返回的结果,逻辑相对简单,尽管控件的innerHTML 也被赋值,但这个主要是为了维护作为客户端回调结果显示的小的HTML板的内容,否则就是调用页面中的方法了,那么结果就直接给客户端的回调方法了。
特色三,就是我说的双路的序列化功能了,其实这个场景我们也非常需要,比如我们用客户端回调或XMLHTTP请求获得了一个定单对象,那么客户端修改之 后,我还想把它作为一个客户端调用的输入参数,返回到服务器端。这时候两路双向的序列化就需要了,因为这次服务器需要将Javascript的函数传了的 数据序列化成.NET的类。这也就是JSON的双向序列化了(主要代码在JSONSerializer.cs ),这也是我挺喜欢的一个功能,因为我对这个功能关注很久,但是目前流行的AJAX-NET的框架都不支持这个功能。
Anthem.NET
目前是1.0版本,其设计理念是通过另外一个思路,遵循这样的理念--既然ASP.NET的各个标准控件没有实现提交功能,那么我可以产生一个提交的接口,然后继承原来的标准控件,然后再实现这个接口,这样每个控件都可以向服务器端单独进行提交。
每个控件的发生过程类似MagicAJAX.NET,Anthem.NET提供了各个控件Javascript端的提交函数-这等于也截取了 __doPostBack,之后Anthem.NET 还提供了完善的客户端的事件比如PostCallBack 和PreCallBack 这样的客户端事件,之后也将使用XMLHttpRequest 模拟一个传统的页面提交请求到服务器端,服务器端生成页面实例,这个过程和MagicAJAX.NET一样,最后是将Rendered的HTML在控件的 Render() 事件传回到客户端,客户端控件的innerHTML被赋值,动态更新。
和MagicAJAX.NET不同的是, Anthem.NET没有容器的概念,因为每个控件都增加了提交接口,所以可以单独的提交,所以单位是以一个控件为单位进行一次提交, Anthem.NET的花费更小些(但服务器端是类似的,因为整个ASP.NET页面的Pipeline都会进行)。
此外, Anthem.NET 还有另外的功能,就是可以通过客户端调用页面中的方法并获得结果/数据,这种情况下,你将调用Anthem_InvokePageMethod 方法,而不是Anthem.NET提供的默认各个控件的提交方法。这样Javascript的回调处理函数中的result.value 将可以获得调用的服务端的某个方法(该方法以[Anthem.Method]为标记)的执行结果,因为JavascriptPost的数据中有 Page/MasterPage/Control 了,那么服务器端很容易通过这个标识获得方法的地址,应用反射寻找[Anthem.Method]标记,然后调用,将结果返回到客户端。
Anthem.NET支持返回对象,DataSet,DataTable和 WriteDataRow(WriteDataSet,WriteDataTable,WriteDataRow,WriteObject),返回的是符 合是JSON规范的字符串,这样客户端的Javascript就可以使用这些对象了。不同于MagicAJAX.NET,Anthem.NET 没有使用HTTP Model,所以结果是在页面的PreRender() 事件中处理和返回请求的结果。
目前在wwHoverPanel 的场景中,我认为这是一种轻量级的实现,对于多层嵌套多组引用的对象图类型或是大规模容量访问压力下,客户端和服务器端都还需要优化,所以如果其作为AJAX架构,客户端和服务器端通信和传递数据的通讯层上,显然是有些单薄了。 wwHoverPanel 的一些不足和想法:
Atlas
这个产品,我就不列举具体的功能了,而主要说一下我对其的看法和持有的态度。因为在我的AJAX书评中提到过问题。
Atlas 是一个个性鲜明的产品,其优点是明显的,缺点也是明显的,但首先你必须认识到它还是一个比较复杂,拥有较高学习曲线的解决方案。对于其复杂性,老实说目前,大多数人还缺乏真实的感受。
最近的一个个版本-Jan CTP,我们看到了一些特性,其强大之处在于:
但缺点也是明显的,比如:
我并不建议,你现在就将它应用在一个老的ASP.NET 项目中,或是老项目迁移到ASP.NET v2.0时优先考虑它;更多时候,如果你是创建一个新的ASP.NET应用,而又跨越了其学习曲线的情况下,可以考虑使用它。目前的情况下,对于 Atlas,我建议,你应该保持足够的关注和实践学习,但是要抑制住将其应用到项目中的兴趣;因为AJAX,你现在可以开始关注和学习它,但是你不能因为 要实现AJAX一个特性,而立即选择Atlas,那么是可能有风险的。
注: Atals 的Microsoft.Web.Script.Serialization 命名空间中有JavaScriptObjectDeserializer和JavaScriptObjectSerializer两个对象,第一,我不确 定其是否也是JSON 序列化,而且我也不确定目前是否支持两路双向的序列化;第二,目前的版本,我还不能进行自定义或扩展,同时也很难对于其性能做任何的结论 。