随笔-313  评论-12138  文章-1  trackbacks-256

使用ASP.NET AJAX异步调用Web Service和页面中的类方法(7):服务器端和客户端数据类型的自动转换:泛型集合类型

本文来自《ASP.NET AJAX程序设计 第II卷:客户端Microsoft AJAX Library相关》的第三章《异步调用Web Service和页面中的类方法》,请同时参考本章的其他文章

3.7.4 泛型集合类型

.NET Framework 2.0中新引入的泛型集合类型不但能够大大提高程序的执行效率,也能让IDE在编译前就能了解更多的类型信息,进而在我们的开发过程中提供更完善的辅助信息。因此,作为“传统”集合的替代品,泛型集合类型正被越来越广泛地使用于各种.NET应用程序中。

ASP.NET AJAX异步通讯层也能够为常用的泛型集合类型自动生成相应的客户端JavaScript类型,让我们可以方便地在客户端和服务器端传递集合类型的数据。

对于泛型集合类型中的类型T,若为简单类型,那么ASP.NET AJAX异步通讯层将自动为我们生成客户端JavaScript类型。例如对于如下返回List<int>类型的Web Service方法:

[WebMethod]
public List<int> GetGenericIntList()
{
    List<int> intList = new List<int>();
    for (int i = 0; i < 10; ++i)
    {
        intList.Add(i * 10);
    }
 
    return intList;
}

若是为该Web Service添加了[ScriptService]属性,且用ScriptManager控件将其引入到了页面中的话,那么在客户端即可直接调用该Web Service方法。ASP.NET AJAX异步通讯层将自动把返回的List<int>类型转换为JavaScript中的数组,图3-22显示了返回值在Visual Studio调试器中显示出的结构。

图3-22 服务器端List<int>类型在客户端的结构

考虑如下接收一个List<int>参数的Web Service方法:

[WebMethod]
public void SendGenericIntList(List<int> intList)
{
    // ......
}

我们即可用如下客户端代码将某个JavaScript数组传递到该SendGenericIntList()方法中,注意SendGenericIntList()方法所在的Web Service类为PeopleManagementService:

var intList = new Array();
for (var i = 0 ; i < 10; ++i) {
    intList.push(i);
}
PeopleManagementService.SendGenericIntList(intList);

ASP.NET AJAX异步通讯层将自动把这个JavaScript数组转换为服务器端的List<int>类型,在程序运行中,SendGenericIntList()方法根本不会有所察觉。图3-23显示了传入参数在Visual Studio调试器中显示出的结构。

图3-23 客户端JavaScript数组可被自动转换为服务器端List<int>类型

而若是泛型集合类型中的类型T为复杂类型,那么我们则需要为Web Service类添加[GenerateScriptType(typeof([TypeName]))]属性,其中[TypeName]表示该复杂类型的名称。我们还是以前面的Employee类为例,考虑下面这个返回一个List<Employee>类型的Web Service方法:

[WebMethod]
public List<Employee> GetGenericEmployeeList()
{
    List<Employee> employeeList = new List<Employee>();
    for (int i = 0; i < 10; ++i)
    {
        Employee em = new Employee(
            i,
            string.Format("name {0}", i),
            string.Format("name{0}@some.com", i),
            5000
        );
        employeeList.Add(em);
    }
 
    return employeeList;
}

客户端调用该Web Service方法的代理之后,ASP.NET AJAX异步通讯层将自动把返回的List<Employee>类型转换为JavaScript中的数组,图3-24显示了返回值在Visual Studio调试器中显示出的结构。

图3-24 服务器端List<Employee>类型在客户端的结构

考虑如下接收一个List<Employee>参数的Web Service方法:

[WebMethod]
public void SendGenericEmployeeList(List<Employee> employeeList)
{
    // ......
}

我们即可用如下客户端代码将某个包含客户端Employee对象的JavaScript数组传递到该SendGenericEmployeeList()方法中:

var employeeList = new Array();
for (var i = 0; i < 10; ++i) {
    var em = new Employee();
    em.Id = i;
    em.Name = "name " + i;
    em.Email = "name" + i + "@some.com";
    em.Salary = 9000;
    
    employeeList.push(em);
}
PeopleManagementService.SendGenericEmployeeList(employeeList);

ASP.NET AJAX异步通讯层将自动把这个JavaScript数组转换为服务器端的List<Employee>类型,SendGenericEmployeeList()方法同样不会有所察觉。图3-25显示了传入参数在Visual Studio调试器中显示出的结构。

图3-25 客户端包含Employee对象的JavaScript数组可被自动转换为服务器端List<Employee>类型

对于Dictionary<TKey, TValue>类型,ASP.NET AJAX异步通讯层也可以将其自动转换为客户端的相应类型——当然前提是如果TKey或TValue属于复杂类型,我们仍需要为Web Service类添加[GenerateScriptType(typeof([TypeName]))]属性,其中[TypeName]表示TKey或TValue复杂类型的名称。

我们还是以前面的Employee类为例,考虑如下服务器端Web Service方法:

[WebMethod]
public Dictionary<string, Employee> GetGenericEmployeeDictionary()
{
    Dictionary<string, Employee> employeeDict = new Dictionary<string, Employee>();
    for (int i = 0; i < 10; ++i)
    {
        Employee em = new Employee(
            i,
            string.Format("name {0}", i),
            string.Format("name{0}@some.com", i),
            5000
        );
        employeeDict[em.Id.ToString()] = em;
    }
 
    return employeeDict;
}

若是为该Web Service添加了[ScriptService]属性,且用ScriptManager控件将其引入到了页面中的话,那么在客户端调用该Web Service方法的代理即可得到Dictionary<string, Employee>相应的客户端JavaScript对象。客户端调用该Web Service方法的代码如下:

function pageLoad() {
    PeopleManagementService.GetGenericEmployeeDictionary(onSucceeded);
}

onSucceeded()回调函数的代码如下,将GetGenericEmployeeDictionary()方法的返回值显示成一个表格,注意其中的for (var key in result)语句,用来遍历该客户端Dictionary中的键/值对:

function onSucceeded(result) {
    var tableBuilder = new Sys.StringBuilder("<table border=1>");
    
    // 创建表格标题行
    tableBuilder.append(
        "<tr><td>Id</td><td>Name</td><td>Email</td><td>Salary</td></tr>"
    );
    
    for (var key in result) {
        var employee = result[key];
        // 创建表格内容行
        var rowString = 
            String.format(
                "<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td></tr>",
                employee.Id,
                employee.Name,
                employee.Email,
                employee.Salary
            );
        tableBuilder.append(rowString);
    }
    
    tableBuilder.append("</table>");
    
    $get("result").innerHTML = tableBuilder.toString();
}

运行本程序,我们将看到如图3-26所示的界面。

图3-26 取得服务器端Dictionary<string, Employee>类型的数据,并显示成表格

posted on 2007-06-13 00:03 Dflying Chen 阅读(4852) 评论(27) 编辑 收藏

评论:
#1楼 2007-06-13 08:25 | 若寒      
想不到是沙發呀!!哈。
原來用javascript還可以Send一個集合到Service。不錯!!

 回复 引用 查看   
#2楼 2007-06-13 09:16 | yao[未注册用户]
将结果用table的形式显示出来,感觉有点像回到asp时代了,哈哈.
有没有客户端的控件,用来显示result结果的呢?

 回复 引用   
#3楼 2007-06-13 09:23 | 小鬼[未注册用户]
ASP时代是个好时代哦.
 回复 引用   
#4楼 2007-06-13 09:32 | m[未注册用户]
take care
 回复 引用   
#5楼[楼主] 2007-06-13 09:41 | Dflying Chen      
@若寒
呵呵,还有很多功能呢

 回复 引用 查看   
#6楼[楼主] 2007-06-13 09:42 | Dflying Chen      
@yao
恩,程序主要演示的是异步通讯层的功能,至于数据是如何表现的,这里并没有太多在意。
客户端提供了很多功能丰富的控件,本书其它章节中有详细介绍

 回复 引用 查看   
#7楼[楼主] 2007-06-13 09:42 | Dflying Chen      
@小鬼
何谈好时代阿,呵呵

 回复 引用 查看   
#8楼[楼主] 2007-06-13 09:42 | Dflying Chen      
@m
谢谢

 回复 引用 查看   
#9楼 2007-06-13 09:46 | yao[未注册用户]
很期待客户端的控件这部分内容. 不知道老大会不会把这部分的内容也在您的BLOG上发表出来呢.
 回复 引用   
#10楼[楼主] 2007-06-13 09:49 | Dflying Chen      
@yao
这部分内容太多了,可以适当放出一点。具体多少,还需要和出版社协商后再作定夺。
谢谢!

 回复 引用 查看   
#11楼 2007-06-13 10:11 | Dong[未注册用户]
AJAX+WebService 真是不错的组合:)
 回复 引用   
#12楼 2007-06-13 10:18 | yao[未注册用户]
少放一点尝尝鲜也不错. 期待您的第二册书早日出版, 这样就可以一窥全貌了.
 回复 引用   
#13楼 2007-06-13 10:21 | 里奥特      
紧跟着学习啦..
还在熬夜呀,哈哈.

图3-23下面的代码有点错误:

string.Format("name{0}@some.com"),5000

这个反括号应该放在后面.估计是晚上....

 回复 引用 查看   
#14楼[楼主] 2007-06-13 10:26 | Dflying Chen      
@Dong
是啊,挺好的

 回复 引用 查看   
#15楼[楼主] 2007-06-13 10:27 | Dflying Chen      
@yao
谢谢支持,我会尽力争取的

 回复 引用 查看   
#16楼[楼主] 2007-06-13 10:27 | Dflying Chen      
@里奥特
改过来了,谢谢提醒!

 回复 引用 查看   
#17楼 2007-06-13 11:39 | Jeffrey Zhao      
@Dong
WebService是假的,其实只是调用了服务器端的方法。
本质上和AJAX.NET里调用页面上的方法是一样的。

 回复 引用 查看   
#18楼 2007-06-13 15:20 | Anthan      
@Jeffrey Zhao
客户端支持直接调用页面中的方法为什么还要用WebService呢?
WebService有他的好处和坏处啊。

 回复 引用 查看   
#19楼 2007-06-13 15:49 | Leepy      
每天都要进来看看,每天都能学到东西,真好!
 回复 引用 查看   
#20楼[楼主] 2007-06-13 16:18 | Dflying Chen      
@Jeffrey Zhao
呵呵,为了便于理解,还是这样说比较合适

 回复 引用 查看   
#21楼[楼主] 2007-06-13 16:19 | Dflying Chen      
@Anthan
提供了另外一种选择吧,让架构变得更加清晰

 回复 引用 查看   
#22楼[楼主] 2007-06-13 16:19 | Dflying Chen      
@Leepy
谢谢支持

 回复 引用 查看   
#23楼 2007-06-13 16:33 | Anthan      
@Dflying Chen
只是不同架构吗?性能,易用性,安全性上有得到提升吗?

 回复 引用 查看   
#24楼[楼主] 2007-06-13 16:34 | Dflying Chen      
@Anthan
基本上大同小异吧,呵呵

 回复 引用 查看   
#25楼 2007-06-13 23:40 | Michael[未注册用户]
讲得不错呵,另有一问题请教,asp.net ajax能实现像chinaren实现各个小栏目拖曳缩放功能吗?谢谢!
 回复 引用   
#27楼 2009-02-10 13:31 | yinix      
太牛了阿。
 回复 引用 查看   
除非特别声明,本站内所有资源,包括但不限于文章,代码,图片等,均应用于Dflying版权说明
关于ASP.NET AJAX,您可以:
直接阅读ASP.NET AJAX文章分类
Atlas文章打包下载(截至4/28/2006)
加入ASP.NET AJAX学习团队
询问关于ASP.NET AJAX的问题
加入ASP.NET AJAX讨论群
阅读愚作《ASP.NET AJAX程序设计》
点击阅读
点击阅读


关于Windows Vista,您可以:
加入Windows Vista开发团队!
昵称:Dflying Chen
园龄:5年10个月
粉丝:127
关注:0

搜索

 
 

最新随笔

随笔分类(352)

随笔档案(313)

Blog Roll

Dflying的其他Blog

Online Chat

统计信息

积分与排名

  • 积分 - 2442908
  • 排名 - 7

最新评论

阅读排行榜

评论排行榜