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,"",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>
執行結果如下