上一篇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
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
<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
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
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
<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
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
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
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对象通过什么样的形式发送到服务器端呢??希望各位能够提供一些建议。
源代码下载