原文地址 http://www.baodr.com/post/2008/03/AJAX-e5bfabe9809fe5ba94e794a8efbc88Michael-Schwarz-ajaxdll-e7af87efbc89.aspx
概述
在这个系列中我会重点介绍一下 Michael Schwarz 的 AJAX .NET 程序集 (后文就称它为 ajax.dll 或 Ajax 包装器),通过它 ASP.NET 开发人员可以快速方便的部署很容易利用 AJAX 功能的页面。虽然在 VS2005 和 VS2008 中已经把 Ajax 集成到开发环境中,但 Michael Schwarz 的 Ajax .net 程序集却给我们提供了一个轻量级的解决方案 (如果你还在用 2003 开发你的程序它的帮助还是很大的嗷)。需要注意的是,这个程序集尚处在初期开发阶段,因此还没有完全成熟。(你可以在示例代码中找到最新的程序集)
Asynchronous JavaScript and XML (Ajax) 的概念在这里就不多说了,其实 Ajax 的流行一部分要归功于 Google 在 Google Suggest 和 Google Maps 中的应用。对 ASP.NET 而言, Ajax 不需要回传就能进行服务器端处理,从而使客户机 ( 浏览器 ) 具有丰富的服务器端能力。也就是说,它为异步提交和处理请求与服务器响应提供了一个不同于以往 asp.net 中 post back 的框架。 Ajax 的技术并不是太新,但如果把 Ajax 技术和概念应用到我们的 WEB 程序中会给我们焕然一新的感觉。 有一点值得注意的是, AJAX 很可能破坏分层体系结构 (N-Tier) ,它增加了表示逻辑层 ( 甚至更糟,业务层 ) 渗透到表示层的可能性。如果你是一个严肃的架构师你可能不太喜欢这种技术。我感觉,这要视具体的项目和环境而定。
To learn more about AJAX, visit:
http://en.wikipedia.org/wiki/AJAX
http://www.adaptivepath.com/publications/essays/archives/000385.php
起步:它是如何工作的
AJAX 依靠代理 (broker) 指派和处理往返服务器的请求。对此, Ajax 包装器 (ajax.dll) 同样依靠客户端 XmlHttpRequest 对象。多数浏览器都支持 XmlHttpRequest 对象,这就是选择它的原因。在这里我们就不讨论 XmlHttpRequest 的实现了,因为 ajax.dll 的目的就是隐藏 XmlHttpRequest 的实现,我们就不再详细讨论它了。 Ajax.dll 是通过将 .NET 函数标记为 AJAX 方 法来工作的,一旦标记 包装器 (ajax.dll) 就创建对应的 JavaScript 函数,这些函数 ( 和任何 JavaScript 函数一样 ) 作为代理可以在客户端使用 XmlHttpRequest 调用。这些代理再映射回服务器端函数。
下面是一个简单的例子。假设有一个 .NET 函数,并将它标记为 :
- [AjaxPro.AjaxMethod ()]
- public int ServerSideAdd(int firstNumber, int secondNumber)
- {
- return firstNumber + secondNumber;
- }
Ajax.dll 将自动创建名为 “Add” 、带有两个参数的 JavaScript 函数。使用 JavaScript( 在客户机上 ) 调用该函数时,请求将传递给服务器并把结果返回给客户机。
初始设置
我们首先了解一下在 asp.net 项目中注册 ajax.dll 的步骤。如果您很清楚如何添加 dll 文件引用,可以跳过这一节。
首先 ,如果还没有的话,请下载最新的 AJAX 版本(本 post 示例中提供或到 CodePlex 中下载)。在 Visual Studio.NET 中点击 Solution Explorer 的 “References( 引用 )” 节点并选择 Add Reference( 添加引用 ) 。在打开的对话框中,单击 Browse( 浏览 ) 并找到 Ajax.dll 或 AjaxPro.2.dll (最新的)文件。依次单击 Open( 打开 ) 和 Ok( 确认 ) 。这样就可以在项目中用 ajax.dll 了。
建立 HttpHandler
还有一个必须要设置的步骤,就是我们要让所有对 Ajax/*.ashx 的请求由 Ajax.PageHandlerFactory 类来处理。所以我们还需要在 web.config 中设置 ajax.dll 的 HttpHandler 。 HttpHandler 是什么及其如何工作 ( 参考一下 MSDN ) ,这里只要知道它们用于处理 ASP.NET 请求就足够了。
- < system.web >
- < httpHandlers >
- < add verb = "POST,GET " path = "*.ashx " type = "AjaxPro.AjaxHandlerFactory, AjaxPro.2 "/>
- </ httpHandlers >
- </ system.web >
简单的说,上面的代码告诉 ASP.NET ,对指定路径 (Ajax/*.ashx) 匹配的任何请求都由 Ajax.PageHandlerFactory 而不是默认处理程序工厂来处理。不需要创建 Ajax 子目录,使用这个神秘的目录只是为了让其他 HttpHandlers 能够在自己建立的子目录中使用 .ashx 扩展。
建立页面
现在我们可以开始编码了。
可以看到 IDE 的智能提示,我们已经注册成功。
创建 一个新页面或者打开已有的页面,在 file 后的代码中,为 Page_Load 事件添加以下代码 :
- protected void Page_Load(object sender, EventArgs e)
- {
- AjaxPro.Utility .RegisterTypeForAjax(typeof (_DefaultCS ));
- }
调用 RegisterTypeForAjax 将在页面对类型进行注册,以便在客户端识别并引发 JavaScript 脚步 ( 或者 在页面中手工加入以下两行代码 ):
< script language ="javascript" src ="Ajax/common.ashx"></ script > < script language ="javascript" src ="Ajax/Namespace.PageClass,AssemblyName.ashx"></ script >
其中最后一行的含义是 :
- Namespace.PageClass —— 当前页面的名称空间和类 ( 通常是 @Page 指令中 Inherits 属性的值 )
- AssemblyName —— 当前页面所属程序集的名称 ( 通常就是项目名 )
下载 示例,在 VS2005 中运行 Default.aspx 看看它是怎么运行的。
创建服务器端函数
现在来创建可从客户端调用中异步访问的服务器端函数。因为目前还不支持所有的返回类型 ( 不用担心,应该会不断有新的版本出现 – 关注 Michael Schwarz ) ,我们继续使用简单的 ServerSideAdd 函数。在 file 后的代码中,向页面添加下列代码 :
- [AjaxPro.AjaxMethod ()]
- public int ServerSideAdd(int firstNumber, int secondNumber)
- {
- return firstNumber + secondNumber;
- }
注意: 这些函数具有 Ajax.AjaxMethod 属性集。该属性告诉包装器这些方法需要创建 javaScript 代理,以便在客户端调用。
客户端调用
最后一步是用 JavaScript 调用该函数。 AJAX 包装器负责创建带有两个参数的 JavaScript 函数 Sample.ServerSideAdd 。对这种最简单的函数,只需要调用该方法并传递两个数字 :
- < script language ="javascript" type ="text/javascript">
- var response = _DefaultCS.ServerSideAdd(100,99);
- alert(response.value);
- </ script >
当然 ,我们不希望仅仅用这种强大的能力来 alert 信息给用户。这就是所有客户端代理 ( 如 JavaScript Sample.ServerSideAd 函数 ) 还接受其他特性的原因。这种特性就是为了处理响应而调用的回调函数 :
- _DefaultCS.ServerSideAdd(100,99,ServerSideAdd_CallBack);
- function ServerSideAdd_CallBack(response)
- {
- if (response.error != null)
- {
- alert(response.error);
- return;
- }
- //alert(response.value);
- }
从上述代码中可以看到我们指定了另外一个参数。 ServerSideAdd_CallBack 是用于处理服务器响应的客户端函数。这个回调函数接收一个响应对象,该对象公开了三个主要性质:
- Value —— 服务器端函数实际返回的值 ( 无论是字符串、自定义对象还是数据集 ) 。
- Error —— 错误消息,如果有的话。
- Request ——xml http 请求的原始响应。
- Context —— 上下文对象。 首先我们检查 error 只看看是否出现了错误。通过在服务器端函数中抛出异常,可以很容易处理 error 特性。 在这个简化的例子中,用这个值警告用户。 Request 特性可用于获得更多信息。
下一篇我们会重点 介绍通过 Michael Schwarz 包装器进行复杂类型处理,继续关注......