ASP.NET AJAX客戶端編程之旅(三)——讓JavaScript和C#無障礙溝通:數據類型自動轉換&序列化(轉載)

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:

 1using System;
 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:

 1using System;
 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:

 1function btnShowStudentInfo_onClick()
 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:

 1<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
 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月

作者:T2噬菌體
出處:http://leoo2sk.cnblogs.com
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章