ASP.NET 中更简洁、更快的 AJAX






4.47/5 (10投票s)
本文快速概述了 AJAX 如何帮助解决 Web 应用程序的慢速部分,并重点介绍 ASP.NET 中的一种新方法。
引言
许多 Web 应用程序公司花费大量时间和精力进行市场研究、分析需求,并提出各种精妙的方法来为用户提供比竞争对手更多的价值。但仅有业务价值并不能保证高采用率。您的应用程序需要表现出色——没有人想要缓慢且难以使用的东西。本文快速概述了 AJAX 如何帮助解决慢速部分,并重点介绍 ASP.NET 中的一种新方法。
概述
为许多 Web 应用程序提供良好的用户体验通常意味着使它们的工作方式非常类似于我们已经习惯的旧式桌面应用程序。开发人员一直在使用 AJAX(异步 JavaScript 和 XML)技术为用户提供类似桌面应用程序的功能和行为。
随着 Web 应用程序变得越来越复杂,并且数据密集度越来越高,许多使用标准 ASP.NET AJAX 技术的 Web 应用程序发现,虽然这些技术在可用性方面具有明显优势,但对于需要处理和显示大量数据的 Web 应用程序来说,它们的性能往往不尽如人意。
AJAX
ASP.NET 提供了几种使用 AJAX 功能的方法,但它们背后的思想是相似的。AJAX 允许 Web 页面在后台连接到 Web 服务器,而不是在用户执行某个操作后刷新用户的 Web 页面或将其重定向到另一个页面。指令被发送,新信息被接收以供界面使用——无论是显示消息还是更改视图。
ASP.NET Web 应用程序中最常见的两种 AJAX 方法是使用 UpdatePanel
和部分回发。两者都提供易于实现的特性和丰富的功能集。虽然这些对于相对较小的网页来说可能是理想的选择,但两种方法在每次调用时都会在网络上传输大量数据。这对于频繁使用 AJAX 发送和接收数据的网页来说,可能会导致性能严重下降。
虽然 ASP.NET 提供了不同风格的 AJAX 实现,如上述两种,但大多数都在网上得到了广泛的介绍,并且可以通过 Google 找到。因此,在本文中,我想重点介绍一种鲜为人知(但非常有效)的、类似于 Web 服务的方法,称为 PageMethods。
PageMethods
PageMethods 允许任何 ASP.NET 页面定义类似 Web 服务的方法,这些方法可以直接调用,而无需在浏览器和服务器之间来回发送大量数据。这避免了在 ASP.NET 回发中维护 Web 页面状态的典型开销。
您可能会问自己:“我已经这样做了,这里有什么新东西?”主要区别在于,此机制不是在 ASPX 页面的上下文中执行,也不使用回发来执行 AJAX 操作。通过仅包含 Web 服务方法所需的参数,这极大地减少了通过网络提交的数据量,与 UpdatePanel
和部分回发相比,提供了显著的性能提升。
优点和缺点
由于 PageMethods 方法不持久化服务器上的 Web 页面,因此调用这些方法除了方法所需的参数以及最终发送回浏览器的任何数据外,开销很小。这意味着更好的性能和更具响应性的 Web 应用程序。
不幸的是,PageMethods 确实会为改进的性能付出代价。使用这些方法意味着您的服务器代码是在页面上下文之外调用的,这意味着我们都熟悉和喜爱的 ASP.NET 页面对象的许多实用程序和持久性功能都不可用。
事实上,PageMethods 被要求是 static
(VB.NET 中的 Shared
),并且只能操作从浏览器提供给它们的信息,可能还结合了用户的Session 数据。因此,尽管 Page Methods 可以成为在许多 ASP.NET Web 应用程序中提高 AJAX 性能的好方法,但重要的是要权衡性能优势与使用它们所带来的固有复杂性。
实现
实现 PageMethods 非常简单,涉及以下步骤:
- Page Method - 在相关的 ASPX 页面上定义一个静态方法,并为其设置
WebMethod
属性。 - ScriptManager – 向 ASPX 页面添加一个脚本管理器,并启用页面方法。
- JavaScript 异步方法 – 定义两个 JavaScript 方法。一个在 AJAX 调用成功执行后调用,另一个在失败时调用。
- 使用 PageMethods – 使用 JavaScript 从客户端代码调用我们之前定义的 ASPX 静态方法。
要开始,我们需要定义一个静态方法,该方法将由我们的客户端代码使用 JavaScript 调用,看起来可能如下所示:
[WebMethod]
public static string GetData(string text)
{
return text + "-" + DateTime.Now.ToString();
}
为了使用 PageMethods,我们需要使用 ASP.NET AJAX 对象 ScriptManager
。将 ScriptManager
添加到 Web 窗体并将 EnablePageMethods
属性设置为 true
。
<asp:ScriptManager ID="_scriptManager"
runat="server" EnablePageMethods="true" />
由于 PageMethods 调用是异步进行的,我们需要定义一个在 AJAX 调用完成后调用的函数。(注意:在此示例中,我们实际上并没有处理数据,只是显示了一个警报消息。)
function OnGetDataComplete(result, userContext, methodName) {
alert(result);
}
我们还需要定义一个在发生故障时调用的函数,例如连接失败或服务器代码中出现异常。
function OnGetDataError(error, userContext, methodName) {
if (error != null) {
alert(error.get_message());
}
}
最后,我们可以使用此基础结构来检索数据。下面的 JavaScript 函数将调用页面的 Web 服务以及具有结果的适当 JavaScript 函数。
function GetData() {
PageMethods.GetData('this is my data',
OnGetDataComplete, OnGetDataError);
}
高级实现
此时可能会出现的第一个问题之一是如何将复杂数据类型(例如具有多个属性的对象)通过 PageMethods 发送回客户端代码。这可以通过 JSON(JavaScript 对象表示法)来实现。复杂对象可以转换为其 JSON 表示形式,然后可以将其发送回调用客户端并像任何普通对象一样使用。我们可以使用以下函数将任何对象转换为 JSON:
public static string SerializeJsonObject<T>(T obj) where T : class
{
DataContractJsonSerializer serializer =
new DataContractJsonSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, obj);
ms.Flush();
byte[] bytes = ms.GetBuffer();
string json = Encoding.UTF8.GetString(bytes, 0,
bytes.Length).Trim('\0');
return json;
}
}
例如,我们的对象有一个名为 Data
的属性。我们可以修改之前定义的 OnGetDataComplete
JavaScript 函数。我们将 JSON 字符串转换为对象,然后就可以简单地访问其属性。在这种情况下,它恰好是 Data
属性。
function OnGetDataComplete(result, userContext, methodName) {
var myObject = eval('(' + result + ')');
alert(myObject.Data);
}
结论
ASP.NET PageMethods 可能比其他 AJAX 方法更复杂一些,但其改进的性能可以使您的 Web 应用程序更加响应。而且,速度更快总是更好的,对吧?