65.9K
CodeProject 正在变化。 阅读更多。
Home

带 AJAX 的通用数据交换框架

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.69/5 (9投票s)

2006 年 4 月 16 日

CPOL

6分钟阅读

viewsIcon

43978

downloadIcon

122

一个通用的 AJAX 数据交换框架。

引言

互联网编程必须是尴尬且用户不友好的吗?是的,它是,并且将继续如此,直到互联网编程模型从 HTTP/HTML 更改为另一种模型。我已经听到非常愤怒的批评说,这个模型被成千上万的程序员成功地使用了。是的,这是真的。但是,你是否曾经问过自己这样的问题:十多年来互联网存在,却没有一个像样的 HTML 编辑器,这不是很奇怪吗? HTML 页面的开发总是需要调整 HTML 标签。这些编辑器是由无能的初学者开发的吗?不,它们是由非常有能力的人设计的,但 HTML 语言无法胜任。但这还不是全部。服务器和客户端之间的数据交换非常原始。没有通用对象。即使是 ASP.NET,情况也没有太大改善。不幸的是,模型无法立即改变。我们必须为此再忍受几年,而本文将讨论如何解决一些互联网数据交换问题。

统一客户端和服务器编程

用与服务器相同的方式编程客户端(通过对象,而不是通过 HTML 和 DOM 术语)会不会很好?富客户端开发的主要问题是什么?问题在于富应用程序(基于 Windows Forms 或 Web Forms)总是依赖于富对象。富意味着结构良好、分层的类以及操作这些结构的手段。不幸的是,客户端没有任何东西可以帮助完成这项任务。我们有 JavaScript 语言——一种相当不错的语言,它在语法上允许操作结构化数据,但没有机制可以将这些结构从服务器传输到客户端,再从客户端传回服务器。充其量,我们可以使用 XML 解析器。但是,我们必须这样做吗?

这里介绍的框架解决了这些问题。所有对象都源自服务器。我们在服务器上创建几乎任何复杂度的对象(类),初始化它们,将它们注册到框架(RWCDF),然后框架将已经初始化的对象生成给客户端。在客户端完成数据操作后,对象将通过传统的 Postback 或 AJAX(以及)传回服务器。您还可以使用 AJAX 调用直接在服务器上调用方法,并将对象(类)作为参数传递。为了高效地进行数据操作,我们还需要集合。没有像 ArrayListHashtable 这样的动态结构,实现任何严肃的数据操作引擎都非常耗时。框架中已经实现了并包含 JavaScript ArrayListHashtable。换句话说,该框架统一了服务器和客户端的数据操作。有了这个框架,Web 客户端的编程几乎与服务器的编程相同。但请注意,这不是万能药。JavaScript 的性能是主要的障碍。除此之外,JavaScript 的数据类型也非常松散。

框架编程

第一个合乎逻辑的步骤是创建满足我们需求的数据结构。

public class EmployeeAddress
{                            
    public string City;                            
    public string Country;
    public string Street;                        
    public string Phone;    
    public ArrayList PhotoAlbum = new ArrayList();            
}
                            
public class Employee
{                            
    public long somelong = 8598065;            
    public double Salary = 787878.344;
    public float Scale = 8.66F;
    public string Name;                    
    public string  SName;                            
    public string Title;                            
    public string Position;
    public int Age;
    public DateTime Date;                            
    public string PictureUrl;
    public EmployeeAddress Address;
    public bool Married = true;
    public ArrayList SomeDataCollection;
    
    public  Employee                            
    {
        Address = new EmployeeAddress();
    }                            
}

请注意,EmployeeAddress 类的实例是 Employee 类的成员。实际上,嵌套类的深度没有限制。我们创建 Employee 实例并对其进行初始化。

ArrayList MyEmployees = new ArrayList();
Employee emp = new Employee()
emp1.Name = "Bob"; 
emp1.SName = "Smith"; 
emp1.Title = "Mr";
emp1.Position = "waiter";  
emp1.Date = new DateTime(2003, 2, 6);
emp1.Address.City = "London";
emp1.Address.Phone = "(043)8984 63535"; 
emp1.Age = 33;
emp1.PictureUrl = "BobSmith.jpg";

//add employee to ArrayList
MyEmployees.Add(emp); 
//....then create more employees and also add them to ArrayList
MyEmployees.Add(emp1);

之后,我们只需要注册我们希望在客户端上使用的对象 - 在本例中,它是 Employee 对象集合 - MyEmployees

Convertor.RegisterObject("MyObjectKey", MyEmployees);

注册对象的数量没有限制。之后,客户端可以通过 JavaScript 类 ArrayList 访问 MyEmployees 对象。

var EmployeesArrList = _Get("MyObjectKey");

获取第一个员工

var emp = EmployeesArrList.GetAt(0); 
alert(emp.SName + ", " + emp.Name + "," + emp.Title + "," + 
      emp.Position + "," + emp.Address.Street);

其他员工也是如此。

集合中的员工可以被修改并通过传统的 Postback 或 AJAX(以及)发送回服务器。您也可以通过参数为 EmployeesArrList(或其他类)调用服务器上的方法。

var Params = new Array();
Params.push(EmployeesArrList );
var Ret = r.Invoke("ReadEmployeesMethod", Params);

您可以创建 Employee 实例并对其进行初始化

var Emp1 = new Employee ();
Emp1.Name = "Peter";
Emp1.Age = 20;

依此类推……将此员工添加到集合中。

工作原理

服务器上的业务对象被初始化,然后序列化为 XML 格式。然后,此代码将被注入 HTML 页面的 body 中,并发送到客户端进行渲染。数据保存在隐藏字段中。页面加载时,序列化数据会在客户端反序列化为 JavaScript 对象集合。

数据同步

现在我们有了服务器端的数据,形式是 JavaScript 对象,例如 Employee 对象,我们可以更改这些类的字段。

emp.Position = "waiter";

下一步是将对象发送回服务器。这可以通过两种方式完成:Postback 和 AJAX。**更新服务器对象只需要调用方法**。

_Put("MyEmployeesArr", EmpArrList);

在 Postback 发生之前。

更新服务器对象的另一种方法是通过 XmlHttp 发送集合。为此,只需调用

r.Send ("some string data from client"); 

在此特定情况下,字符串“some string data from client”将被发送到服务器。

服务器上定义的(并在客户端上重新创建的)对象,例如 Employee,也可以被发送

r.Send(emp);

或者对象集合

r.Send(EmployeesArrList);

其中 rRemoting(在 Rwc.js 中定义的 JavaScript 对象)。

此外,还可以使用 Invoke 方法(同样在 Rwc.js 中定义)在服务器上调用方法。

var Ret = r.Invoke("ReadABCD", Param1);

其中 ReadABCD 是服务器上的方法名称。Param1 是对象(任何在服务器上定义并注册过的对象)。

这是一个调用 Invoke 的示例

var Params = new Array(); 
Params.push(EmployeesArrList );
var Ret = r.Invoke("ReadEmployeesMethod", Params);

您可以在客户端创建 Employee 实例并对其进行初始化

var Emp1 = new Employee ();
Emp1.Name = "Peter";
Emp1.Age = 20; //..... And so on ...

将此员工添加到集合中

var EmpCollection = new ArrayList();
EmpCollection.Add(Emp1);

添加其他员工并将此集合发送到服务器(Postback/AJAX)。在服务器端,对象以先前已注册的对象实例的形式接收。

在服务器端,通过 AJAX 发送的对象由 l_DataReceivedEvent 处理程序接收。

private object l_DataReceivedEvent(object obj)
{     
    if (obj is Hashtable)
    // check the type of the object sent from the client
    { 
        return "Server: Update OK";
    }
    return "Return a string ";
    // can be returned any registered object
}

如果使用的是标准 Postback,则使用 l_PostBackDataReceivedEvent 处理程序接收对象。

private void l_PostBackDataReceivedEvent(object obj)
{ 
     Hashtable ht = (Hashtable)obj;
     // all objects on the client are packed to hashtable when PostBack is used

    ArrayList emps = (ArrayList)ht["MyEmployeesArr"];
    Convertor.RegisterObject("MyEmployeesArr", emps);       
}

数据类型

没有 JavaScript 表示形式的数据类型是完全无用的。例如,如果一个类有一个成员字段定义为 TimeSpan,那么它就无法转换为 JavaScript。

支持的数据类型

  • int
  • char
  • bool
  • float
  • double
  • 字符串
  • 日期时间
  • ArrayList
  • 哈希表

框架和 ASP.NET 组件

该框架与 ASP.NET 组件无关;它只是一个通用的、结构化的数据传递机制。但是,该框架对于这类组件的设计可能非常有用——它可以为组件提供结构化数据,并可以轻松地与组件框架集成。

在线演示

此处提供一个实时演示:RWC_Live

版本

当前版本是 1.0.2。

致谢

为了获得更好的性能,该框架使用了 Eric Woodruff 的 JavaScript 压缩器。

如果发布了新版本,可以从 www.dotnetremoting.com 下载,以及其他有用的组件。

© . All rights reserved.