CallBack PageCommand 與 JSON 序列化

CallBack PageCommand 與 JSON 序列化

上一篇「CallBack PageCommand 與 JSON」中說明了在 CallBack 時,用戶端可以接收伺服端傳回的 JSON 字串,在用戶端 eval 取得 JSON 物件,使 JavaScript 可以直接操作伺服端傳回的物件。其實在 ASP.NET AJAX 1.0 有提供相關類別來處理伺服端/用戶端的 JSON 序列化/反列序化的需求。

伺服端處理 JSON 序列化的類別為

System.Web.Script.Serialization.JavaScriptSerializer

在伺服端處理序列化/反序列化的函式如下

    ''' <summary>
    ''' JSON 序列化。
    ''' </summary>
    ''' <param name="Value">物件。</param>
    Public Shared Function JsonSerialize(ByVal Value As Object) As String
        Dim oSerializer As System.Web.Script.Serialization.JavaScriptSerializer

        oSerializer = New System.Web.Script.Serialization.JavaScriptSerializer()
        Return oSerializer.Serialize(Value)
    End Function

    ''' <summary>
    ''' JSON 反序列化。
    ''' </summary>
    ''' <param name="Text">JSON 字串。</param>
    Public Shared Function JsonDeserialize(Of T)(ByVal Text As String) As T
        Dim oSerializer As System.Web.Script.Serialization.JavaScriptSerializer

        oSerializer = New System.Web.Script.Serialization.JavaScriptSerializer()
        Return oSerializer.Deserialize(Of T)(Text)
    End Function

用戶端處理 JSON 序列化的類別為

Sys.Serialization.JavaScriptSerializer

JSON 序列化

var sJson= Sys.Serialization.JavaScriptSerializer.serialize(oObject)

JSON 反序列化

var oObject = Sys.Serialization.JavaScriptSerializer.deserialize(sJson)

 

我們來撰寫一個範例測試用戶端/伺服端 JSON 物件的傳遞,程式運作流程如下

用戶端物件 -> 1.用戶端 JSON 序列化 -> CallBack 呼叫伺服端 -> 2.伺服服端 JSON 反序列化還原物件 -> 修改物件屬性

-> 3.服端 JSON 序列化 -> CallBack 回傳用戶端 -> 4.戶端 JSON 反序列化還原物件

 

首先修改 GetCallBackPageCommandEventReference 方法,原本 CommandArgument 是使用字串常數,現修改為呼叫用戶端 GetPageCommandParam 函式。

    ''' <summary>
    ''' 取得以 CallBack 方式引發 PageCommand 事件的用戶端指令碼。
    ''' </summary>
    ''' <param name="CommandName">命令名稱。</param>
    ''' <param name="CommandArgument">命令引數。</param>
    ''' <param name="ClientCallback">可接收成功的伺服器端事件結果的用戶端事件處理常式名稱。</param>
    ''' <param name="Context">在啟始回呼之前,於用戶端上評估的用戶端指令碼。</param>
    Public Function GetCallBackPageCommandEventReference(ByVal CommandName As String, _
        ByVal CommandArgument As String, _
        ByVal ClientCallback As String, ByVal Context As String) As String
        Dim sArgument As String

        'sArgument = String.Format("'{0}${1}${2}'", PageEvent.PageCommand, CommandName, CommandArgument)

        'PageCommand 事件會執行用戶端 GetPageCommandParam 函式
        sArgument = String.Format("GetPageCommandParam('{0}',{1})", CommandName, CommandArgument)
        Return Me.GetCallbackEventReference(FPage, sArgument, ClientCallback, Context)
    End Function

用戶端對應的 GetPageCommandParam 函式如下

    function GetPageCommandParam(commnadName,value){
        var sArgument = Sys.Serialization.JavaScriptSerializer.serialize(value);
        return "PageCommand$"+commnadName+'$'+sArgument;
    }

 

在頁面上放置一個按鈕,利用 GetCallBackPageCommandEventReference 來取得 CallBack PageCommand 的用戶端指令碼。其中 CommandArgument 引數為 GetUser() ,此為執行 CallBack 時執行用戶端的函式。ReceiveServerData 函式則是接收伺服端回傳的結果。

        Button1.OnClientClick = Me.BeeScript.GetCallBackPageCommandEventReference( _
            "User", "GetUser()", "ReceiveServerData", "") & ";return false;"

伺服端的完整程式碼 (aspx.vb) 如下,在 PageCommand 事件中會接收用戶端傳入的 JSON 字串將其轉為物件,修改此物件屬性值再回傳給用戶端。在伺服端會執行程式流程中的「2.伺服服端 JSON 反序列化還原物件」及「3.服端 JSON 序列化」二個步驟。

<Serializable()> _
Public Class TUserData
    Dim FID As String = String.Empty
    Dim FName As String = String.Empty

    Public Property ID() As String
        Get
            Return FID
        End Get
        Set(ByVal value As String)
            FID = value
        End Set
    End Property

    Public Property Name() As String
        Get
            Return FName
        End Get
        Set(ByVal value As String)
            FName = value
        End Set
    End Property
End Class

Partial Class _Default
    Inherits Bee.Web.TBBasePage

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Button1.OnClientClick = Me.BeeScript.GetCallBackPageCommandEventReference( _
            "User", "GetUser()", "ReceiveServerData", "") & ";return false;"
    End Sub

    Protected Sub _Default_PageCommand(ByVal sender As Object, ByVal e As Bee.Web.TBBasePage.PageCommandEventArgs) Handles Me.PageCommand
        Dim oUser As TUserData
        Dim sJson As String

        '2.伺服服端 JSON 反序列化還原物件
        oUser = JsonDeserialize(Of TUserData)(e.CommandArgument)
        oUser.ID = "012"
        oUser.Name = "tony"

        '3.伺服端 JSON 序列化
        sJson = Bee.Web.WebFunc.JsonSerialize(oUser)
        e.CallbackResult = sJson
    End Sub
End Class

 

執行 CallBack 的按鈕,輸出的 HTML 碼如下

<input type="submit" name="Button1" value="執行 PageCommand" onclick="WebForm_DoCallback('__Page',GetPageCommandParam('User',GetUser()),ReceiveServerData,&quot;&quot;,null,false);return false;" id="Button1" />

 

用戶端的 JavaScrpt 程式碼如下所示,其中 GetUser 函式會取得 oUser 類別,包含 ID 及 Name 二個屬性。執行按鈕後會呼叫 GetPageCommandParam 函式,將 GetUser 取得物件執行步驟「1.用戶端 JSON 序列化」,而伺服端回傳給呼叫 ReceiveServerData 函式,執行步驟「4.戶端 JSON 反序列化還原物件」,並顯示 CallBack 後的物件。

 

    <script type="text/jscript">
    function ReceiveServerData(value){
        //4.用戶端 JSON 反序列化還原物件
        var oUser = Sys.Serialization.JavaScriptSerializer.deserialize(value)
        //顯示 CallBack 後的物件
        alert('Server:\n'+'ID:'+oUser.ID+'\nName:'+oUser.Name);
    }
    
    function GetUser(){
        var oUser={
            ID : "007",
            Name : "jeff"
        };
        return oUser;
    }

    function GetPageCommandParam(commnadName,value){
        //1.用戶端 JSON 序列化
        var sArgument = Sys.Serialization.JavaScriptSerializer.serialize(value);
        return "PageCommand$"+commnadName+'$'+sArgument;
    }
    </script>

執行結果如下

image

ASP.NET 魔法學院