使用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  阅读(5877)  评论(27编辑  收藏  举报