上一篇asp.net Ajax 之简单数据回传描述的是客户端向服务器端发送简单的数据(比如string类型),然后由服务器端处理后回传给客户端。这篇主要描述一下一些比较复杂的数据(比如DataTable)在客户端和服务器端交互的情况。在这片随笔中主要通过WebService和页面的静态方法两种形式分别实现同样功能来进行阐述。但主要介绍在WebService下,分别使用数组、IList和DataTable三种数据格式下进行阐述。
    
     上一篇asp.net Ajax 之简单数据回传描述的是客户端向服务器端发送简单的数据(比如string类型),然后由服务器端处理后回传给客户端。这篇主要描述一下一些比较复杂的数据(比如DataTable)在客户端和服务器端交互的情况。在这片随笔中主要通过WebService和页面的静态方法两种形式分别实现同样功能来进行阐述。但主要介绍在WebService下,分别使用数组、IList<T>和DataTable三种数据格式下进行阐述。
一、复杂数据形式之数组
      创建一个WebService文件,暂时我把它命名为WebServiceTest.asmx。因为要在客户端的Javascript函数中调用服务中的函数,所以在WebServiceTest服务加上ScriptService属性。创建ArrayTest_Get()函数返回string[]形式的数据,添加一个ArrayTest_Add(string val)函数,该函数有一个string类型的参数,该参数接收客户端发送过来的值,该函数返回一个ArrayList数组。当然同时给两个函数添加ScriptService属性。如果不加ScriptService属性,页面运行时会提示找不到响应的WebService服务或者响应的函数。具体代码如下:

 Code
Code
 1         [WebMethod]
 2         [ScriptMethod]
 3         public string[] ArrayTest_Get()
 4         {
 5             return new string[] { "Test1", "Test2", "Test3" };
 6         }
 7 
 8         [WebMethod]
 9         [ScriptMethod]
10         public IList ArrayTest_Add(string val)
11         {
12             string[] tmp = new string[] { "Test1", "Test2", "Test3" };
13             ArrayList tmp1 = new ArrayList();
14             for (int i = 0; i < tmp.Length; i++)
15             {
16                 tmp1.Add(tmp[i]);
17             }
18             tmp1.Add(val);
19             return tmp1;
20         }接下来,我们在创建一个ArrayTest.aspx也面,添加ScriptManager控件,并设置Services。具体代码如下:

 Code
Code
    <asp:ScriptManager ID="smArrayTest" runat="server">
            <Services>
                <asp:ServiceReference Path="~/WebServiceTest.asmx" />
            </Services>
        </asp:ScriptManager>
        <script language="javascript" type="text/javascript">
            function onComplete(msg)
            {
                var tmp = '<table  border=\"0px\"><tr><td>名称</td><tr>';
                var len = msg.length;
                for(var i=0;i<len;i++)
                {
                    tmp += String.format("<tr><td>{0}</tr><td>",msg[i]);
                }
                tmp += '</table>'
                
                $get("divshow").innerHTML = tmp;
            }
            function getArray()
            {
                testajax.WebServiceTest.ArrayTest_Get(onComplete);
            }
            function addArray()
            {
                var tmp = $get("txtValue").value;                
                testajax.WebServiceTest.ArrayTest_Add(tmp,onComplete);
            }
        </script>
        <input type="button" value="Get" onclick="getArray()" />
        <input type="text" id="txtValue" />
        <input type="button" value="Add" onclick="addArray()" />        
        <div id="divshow"></div> 编译运行,即可得出结果。
二、复杂数据形式之强类型
      创建一个命名为Person的类(Person.cs文件,在其中添加用于测试的姓名、性别和身份三个属性。Person类代表着是用于测试的强类型。代码如下:

 Code
Code
 1     public class Person
 2     {
 3         private string _name;
 4         private string _gender;
 5         private int _salary;
 6         public Person() { }
 7         public Person(string name, string gender, int salary)
 8         {
 9             this._name = name;
10             this._gender = gender;
11             this._salary = salary;
12         }
13         public string Name
14         { get { return _name; } set { _name = value; } }
15         public string Gender
16         { get { return _gender; } set { _gender = value; } }
17         public int Salary
18         { get { return _salary; } set { _salary = value; } }
19     }     为了方便起见,上面已经创建的WebServiceTest服务添加PersonTest_Get()函数返回Person[],和PersonTest_Add(Person val)函数,其中val是Person类型参数,该函数返回IList<Person>类型数据。代码如下:

 Code
Code
 1         [WebMethod]
 2         [ScriptMethod]
 3         public Person[] PersonTest_Get()
 4         {
 5             return new Person[] { new Person("Nimeux", "Male", 5000), new Person("Test", "Female", 4000) };
 6         }
 7         [WebMethod]
 8         [ScriptMethod]
 9         public IList<Person> PersonTest_Add(Person val)
10         {
11             IList<Person> tmp = new List<Person>();
12             tmp.Add(new Person("Nimeux", "Male", 5000));
13             tmp.Add(new Person("Test", "Female", 4000));
14             tmp.Add(val);
15             return tmp;
16         }     同样创建一个名为wfPersonTest.aspx的页面,页面代码如下:

 Code
Code
     <asp:ScriptManager ID="smArrayTest" runat="server">
            <Services>
                <asp:ServiceReference Path="~/WebServiceTest.asmx" />
            </Services>
        </asp:ScriptManager>
        <script language="javascript" type="text/javascript">
            function onComplete(msg)
            {
                var len = msg.length;
                var tmp = '<table  border=\"1px\"><tr><td>姓名</td><td>性别</td><td>薪水</td><tr>';
                for(var i = 0; i<len ; i++)
                {
                    tmp += String.format("<tr><td>{0}</td><td>{1}</td><td>{2}</td><tr>",msg[i].Name,msg[i].Gender,msg[i].Salary);                    
                }
                tmp += '</table>'
                $get("divshow").innerHTML = tmp;
            }
            function getPerson()
            {
                testajax.WebServiceTest.PersonTest_Get(onComplete);
            }
            function addPerson()
            {
                var person = new testajax.Person();
                person.Name = $get("txtName").value;
                person.Gender = $get("txtGender").value;
                person.Salary = $get("txtSalary").value;
                testajax.WebServiceTest.PersonTest_Add(person,onComplete);
            }
        </script>
        <input type="button" value="Get" onclick="getPerson()" />
        姓名<input type="text" id="txtName" />
        性别<input type="text" id="txtGender" />
        薪水<input type="text" id="txtSalary" />
        <input type="button" value="Add" onclick="addPerson()" />        
        <div id="divshow"></div>在页面代码中,可以看到一段非常有意义的代码:var person = new testajax.Person();看到这段代码是不是非常兴奋呀,有了这种表达形式是不是想到很到地方就可以应用了。我当时看了后第一个反应就是用户注册页面。o(∩_∩)o...
三、复杂数据形式之DataTable
     因为asp.net Ajax不支持DataTable直接在到客户端,如果直接使用DataTable的话就要用实现JavaScriptConverter的Convert,在Ajax.net 1.0的CTP版中,Microsoft.Web.Preview.dll库类中直接可用的Convert,及配置也比较简单,在配置文件下配置就行了

 Code
Code
 1         <system.web.extensions>
 2                  <scripting>
 3                       <webServices>            
 4                         <jsonSerialization>
 5                           <converters>
 6                             <add name="DataSetConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataSetConverter, Microsoft.Web.Preview" />
 7                             <add name="DataRowConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataRowConverter, Microsoft.Web.Preview" />
 8                             <add name="DataTableConverter" type="Microsoft.Web.Preview.Script.Serialization.Converters.DataTableConverter, Microsoft.Web.Preview" />            
 9                           </converters>
10                         </jsonSerialization>        
11                       </webServices>
12                   <scripting>    
13        `</system.web.extensions> 
但在Ajax.net 升级到3.5后,微软就去了这个库类,只提供了JavaScriptConverter,让用户自己写Convert转换程序,这是比较可恶的,但既然以前Microsoft.Web.Preview.dll可以用,那就接着用,反正用起来不赖。
     在配置要配置文件后,接下来就写代码了,和前面的步骤类似。在WebServiceTest服务中添加DataTableTest_Get()函数并返回DataTable,代码如下:

 Code
Code
 1         [WebMethod]
 2         [ScriptMethod]
 3         public DataTable DataTableTest_Get()
 4         {
 5             DataTable dt = new DataTable();
 6             dt.Columns.Add(new DataColumn("Name", typeof(string)));
 7             dt.Columns.Add(new DataColumn("Gender", typeof(string)));
 8             dt.Columns.Add(new DataColumn("Salary", typeof(string)));
 9 
10             DataRow drNew = dt.NewRow();
11             drNew["Name"] = "Test1";
12             drNew["Gender"] = "Male";
13             drNew["Salary"] = "8000";
14             dt.Rows.Add(drNew);
15 
16             drNew = dt.NewRow();
17             drNew["Name"] = "Test2";
18             drNew["Gender"] = "Female";
19             drNew["Salary"] = "6000";
20             dt.Rows.Add(drNew);
21             return dt;      
22         }    创建一个wfDataTableTest.aspx页面,如前面一样编写如下代码:

 Code
Code
 1     <asp:ScriptManager ID="smArrayTest" runat="server">
 2             <Services>
 3                 <asp:ServiceReference Path="~/WebServiceTest.asmx" />
 4             </Services>
 5         </asp:ScriptManager>
 6         <script language="javascript" type="text/javascript">
 7             function onComplete(msg)
 8             {
 9                 var sb = new Sys.StringBuilder("<table border='1' bgcolor='#6699ff'>");
10                 sb.append("<tr><td>姓名</td><td>性别</td><td>工资</td></tr>");
11                 
12                 var l = msg.rows.length;
13                 for(var i = 0;i < l;i++)
14                 {
15                     sb.append(String.format("<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>",msg.rows[i].Name,msg.rows[i].Gender,msg.rows[i].Salary));
16                 }
17                 sb.append("</table>");
18                 $get("divshow").innerHTML = sb.toString();
19             }
20             function getDataTable()
21             {
22                 testajax.WebServiceTest.DataTableTest_Get(onComplete);
23             }
24             
25         </script>
26         <input type="button" value="Get" onclick="getDataTable()" />在这里实现了从服务端直接获取DataTable对象中的数据,但是没有实现在Javascript中实例话一个DataRow或者DataTable,直接使用这个发送数据到服务器端。这个想法可能本然就是错误的,但客户产生的DataTable对象通过什么样的形式发送到服务器端呢??希望各位能够提供一些建议。 
     源代码下载