ASP.NET AJAX客戶端編程之旅(三)——讓JavaScript和C#無障礙溝通:數據類型自動轉換&序列化
摘要
通過前兩篇文章,我們知道使用了ASP.NET AJAX框架後,在JavaScript中調用後臺WebService方法非常方便,幾乎可以看做是“直接調用”。那麼,這裏引出了一個問題:調用方法 就牽扯到參數的傳遞,而JavaScript和C#畢竟是兩種不同的語言,數據類型怎麼溝通?簡單型數據類型還好說,如果我們需要的參數是個複雜類型呢? 如分層架構中經常用到實體類做參數,我們在後臺定義實體類類型,但是JavaScript可不知道這種定義,也沒有相應數據類型,那麼要如何解決這個問題 呢?再進一步,如果需要的參數是個泛型集合呢?在JavaScript中又要如何表示這種類型?這一篇將解決這些問題。
先來看ASP.NET AJAX給你變個魔術
我們都知道,使用分層架構開發系統時,使用實體類作爲參數很很普遍的。那麼如果我們需要調用的某個後臺方法中需要實體類做參數,應該如何進行呢?畢竟C#中定義的實體類在JavaScript中可不認識啊。先不要着急,跟我做以下幾步,我們一起來看個魔術。
1.新建一個ASP.NET AJAX Enabled Web Site工程,並添加系統文件夾App_Code。
2.我們在App_Code裏新建一個C#類文件StudentInfo.cs,其內容如下:
StudentInfo.cs:
2
3[Serializable]
4public class StudentInfo
5{
6 private string _name;
7 private int _age;
8 private string _college;
9
10 public StudentInfo() { }
11
12 public string Name
13 {
14 get { return this._name; }
15 set { this._name = value; }
16 }
17
18 public int Age
19 {
20 get { return this._age; }
21 set { this._age = value; }
22 }
23
24 public string College
25 {
26 get { return this._college; }
27 set { this._college = value; }
28 }
29}
這是一個典型的實體類,相信做過分層架構的朋友一定經常使用到類似的代碼。這裏要特別注意兩點:一是這個類上面有一個[Serializeable]屬性,這表明此類可以被序列化,另外就是這個類有一個空的構造函數。
3.接着,我們在網站根目錄下添加一個WebService:StudentService.asmx,其代碼如下:
StudentService.cs:
2using System.Web;
3using System.Collections;
4using System.Web.Services;
5using System.Web.Services.Protocols;
6using System.Web.Script.Services;
7
8[WebService(Namespace = "http://tempuri.org/")]
9[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
10[ScriptService]
11[GenerateScriptType(typeof(StudentInfo))]
12public class StudentService : System.Web.Services.WebService
13{
14 public StudentService() { }
15
16 [WebMethod]
17 public string ShowStudentInfo(StudentInfo student)
18 {
19 return "學生姓名:" + student.Name + "<br />年齡:" + student.Age + "<br />所在院系:" + student.College;
20 }
21}
ShowStudentInfo這個方法接收一個StudentInfo類型的參數,並根據這個實體類的信息組合成一段字符串返回。
4.接着,在網站根目錄下新建一個ajax.js文件,內容如下:
ajax.js:
2{
3 var student=new StudentInfo();
4 student.Name="張無忌";
5 student.Age="20";
6 student.College="計算機學院";
7
8 StudentService.ShowStudentInfo(student,CallBackFunction);
9}
10
11function CallBackFunction(responseText)
12{
13 $get("result").innerHTML=responseText;
14}
這裏我們大膽的直接初始化了一個StudentInfo,爲什麼說大膽呢?不要忘了,我們的StudentInfo類型可是在C#中定義 的,JavaScript裏可壓根沒有這個類型,當時我們這裏卻好像在寫C#似的,不但初始化了這個類,還給其中成員賦值,並且當作參數傳給了後臺方法。 這樣能成功嗎?我們接着看看吧。
5.Default.aspx作爲主頁,我們添加如下內容:
Default.aspx:
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml">
5<head runat="server">
6 <title>複雜類型自動轉換測試</title>
7</head>
8<body>
9 <form id="form1" runat="server">
10 <asp:ScriptManager ID="ScriptManager1" runat="server">
11 <Scripts>
12 <asp:ScriptReference Path="~/ajax.js" />
13 </Scripts>
14 <Services>
15 <asp:ServiceReference Path="~/StudentService.asmx" />
16 </Services>
17 </asp:ScriptManager>
18 <div>
19 <input id="btnShowStudentInfo" type="button" value="ShowStudentInfo" onclick="btnShowStudentInfo_onClick()" />
20 <div id="result"></div>
21 </div>
22 </form>
23</body>
24</html>
這裏就不用做過多解釋了,看過前兩篇的朋友肯定很容易就明白這段代碼是什麼意思。運行後,我們單擊按鈕,得到如下效果:
可以看到,不僅程序運行沒有報錯,而且我們在JavaScript中定義的實體類被傳到後臺,並神奇的變成了C#實體類,作爲參數完成了數據傳遞工作。運行結果非常令人滿意。
魔術揭祕
在上面的例子中,我們沒有在JavaScript定義StudentInfo,更沒有寫代碼把JavaScript實體類轉換成C#實 體類,但是程序正確執行了。很顯然,有人替我們做了這一切,那是誰呢?當然是我們親愛的ASP.NET AJAX。這就是這個框架另一項神奇的功能:前後臺間數據類型自動轉換,這個轉換可不僅包括簡單類型,還包括像實體類這樣的複雜類型。那麼,其工作原理是 什麼呢?
仔細看StudentService.cs的代碼,在類定義的上面,有一個 [GenerateScriptTyep(typeof(StudentInfo))] 屬性,祕訣就在這裏。當我們給WebService類加上這條屬 性時,ASP.NET AJAX會在運行時自動爲我們生成一個JavaScript版本的StudentInfo類,這個類的所有屬性都和C#版的一模一樣。所以,我們在 JavaScript中實例化並賦值的其實是一個JavaScript版的StudentInfo。而後,當我們調用ShowStudentInfo方法 時,ASP.NET AJAX框架會自動將JavaScript版的StudentInfo序列化成JOSN字符串,然後傳到後臺,後臺再將這段字符串反序列化成C#版的 StudentInfo,並作爲參數傳遞給ShowStudentInfo,從而順利完成工作。
當然,如果某個後臺方法返回一個StudentInfo類型的返回值,它也可以準確無誤從C#傳到JavaScript中。也就是說,序列化和反序列化都是雙向的。
自動轉換的條件
知道了上述原理,那麼如何才能自動轉換呢?或者說具備什麼條件的複雜類型纔可以自動轉換呢?大約有以下幾點:
1.需要在WebService中使用[GenerateScriptTyep()]屬性指明要自動生成的複雜數據類型。
2.該複雜類型必須有一個無參數的構造函數。
3.該複雜類型的所有公有屬性必須有get和set方法。
另外值得注意的是,生成的JavaScript版本類只包含原類的公有屬性,而私有屬性和方法是不會映射過來的。應該說,這個技術對使用分層架構的應用特別有用,因爲可以直接在客戶端使用服務器端的實體類進行數據傳輸。
ASP.NET AJAX到底能自動轉換哪些數據類型?
1.基本類型將被轉換爲基本類型。如整形、浮點型、字符串、布爾型、DateTime等。(全自動轉換)
2.枚舉類型將被轉換爲枚舉類型。(全自動轉換)
3.複雜類型將轉換爲同名複雜類型,但只保留公有屬性。(需要使用[GenerateScriptTyep(typeof(TypeName))]屬性聲明)
4.數組、泛型集合將轉換爲數組。(全自動轉換)
5.DataTable將轉換爲JavaScript版的DataTable,但是需要ASP.NET Futures CTP的支持。
結束語
這一篇中介紹了ASP.NET AJAX中非常有用的一個特性:數據類型自動轉換。通過這個功能,使得前臺可以更方便的調用後臺程序。尤其是使用實體類傳遞數據會變得非常方便。在下一篇 中,將介紹客戶端組件的概念、使用客戶端組件思想進行JavaScript開發以及簡化的DOM操作。
本文用到的實例可以在這裏下載:AutoConvertionTest.rar
主要參考文獻
[1] 陳黎夫,ASP.NET AJAX程序設計-第II卷:客戶端,人民郵電出版社,2007年10月
出處:http://leoo2sk.cnblogs.com
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。