ASP.NET2.0客戶端回調的實現分析
友情提醒:ASP.NET初學者入門最佳實踐
開發人員使用JavaScript的一個主要原因就是可以避免回發過程中帶來的頁面刷新。例如我們可以根據用戶的需要使用Treeview控件來展開和折疊相應的數據節點。當你展開一個節點時,該Treeview控件將會利用JavaScript讀取服務器上的子節點信息,然后平滑無刷新地插入這些新節點。如果沒有使用JavaScript的話,Treeview控件將會因為頁面的回發而重新構建。不但用戶會發現因頁面刷新而帶來的延遲,而且頁面極有可能回復到原來的狀態,即丟失前面所展開的那些子節點信息。對于服務器端來說,因為每次回發的過程中都要處理大量的視圖狀態(View State)信息,這也會嚴重影響程序的整體執行性能。
以前我們使用的JavaScript示例幾乎都是自包含的,即它們通常是為了完成一些特殊的顯示效果(例如彈出一個新的頁面窗口),而沒有和服務器端代碼進行信息的交互。如果你也想構建一個類似的無刷新頁面的話,你首先必須調用服務器端的一個特定的方法,等待服務器響應后就會將請求的信息傳遞到客戶端,從而避免了回發這個過程。為了實現這個方案,你首先需要對如何將客戶端腳本和服務器端代碼進行通訊有個大致的了解。盡管有許多中方法可以實現這兩者間的交互(例如調用Web服務),但是由于受到特定的瀏覽器和平臺的限制,它們的實現是還是有一定的難度的。而在ASP.NET 2.0中,引入了一個稱為"客戶端回調"的功能,利用這個內建的解決方案我們可以輕松實現客戶端腳本和服務器端代碼間的交互,從而避免了頁面因回發帶來的頻繁刷新。
版權聲明:任何獲得天極網授權的網站,轉載時請務必保留作者信息和以下鏈接
天極開發ASP.NET專欄:http://dev.yesky.com/msdn/msdnasp/
客戶端回調本質上就是指通過前端的客戶端腳本向服務器端傳遞相應的數據參數,服務器端再以接受到的參數進行查詢和處理,最后將結果回傳到客戶端進行顯示。雖然這樣的過程不是一種創舉,但是對于許多開發者來說這在某種思維上還是無法理解的,因為JavaScript的內存管理和.NET CLR的內存管理是不同的進程,而且管理的空間上也截然不同,所以彼此間無法直接參照也沒有直接進行交互的方式,而客戶端回調卻是實現客戶端和服務器端進行溝通的方法之一,又因為它是在客戶端觸發的,所以這就應該是"客戶端回調"命名的由來吧!
創建一個簡單的客戶端回調
為了在ASP.NET中展示一個客戶端回調的實例,首先我們將概述客戶端回調間的交互過程是如何實現的。下面是基本的步驟:
1. 在某時刻激活一個JavaScript事件,從而觸發客戶端回調。
2. 觸發客戶端回調發生后,服務器端的一個方法將被執行。該方法有一個固定的模式――它接受的是一個字符串參數,并且返回的也是一個字符串參數。
3. 一旦頁面接受到來自服務器端方法的響應結果后,它就可以利用JavaScript修改一些和用戶界面有關的信息(例如顯示在頁面上顯示返回的結果)
對于開發人員來說,底層的交互過程是非常復雜的,ASP.NET則將交互的處理過程進行了抽象化,這樣使得開發人員可以直接建立表層的客戶端回調,而無需考慮底層的操作是如何實現的。
下面的實例中,頁面中放置了一個文本框,一個提交按鈕和一個標簽。文本框是用來接受用戶的輸入信息,在單擊提交按鈕后將把文本框中輸入的信息在標簽上進行實時的顯示。注意,在輸入信息后單擊提交按鈕時,并沒有像以前傳統的提交方式那樣重新對頁面進行構建和刷新。圖1-1為該實例的效果圖。
創建基本的頁面
按照上圖的布局在工具欄的"標準"標簽中拖拽出一個TextBox控件,一個Label控件到主窗體上。然后在"HTML"標簽中拖拽出一個InputButton的HTML按鈕,注意,該按鈕不是我們經常使用的服務器端控件,而是一個HTML元素。在按鈕中添加一個onclick事件,點擊該按鈕這將向服務器端發出回調請求,這個onclick事件的具體實現細節將在以后的過程中加以說明。得到的初始頁面代碼如下:
執行回調
為了實現客戶端回調,你的頁面邏輯代碼中必須實現一個ICallbackEventHandler接口。代碼如下:
ICallbackEventHandler接口定義了兩個方法,RaiseCallbackEvent()從瀏覽器接受一個字符串作為事件參數,即該方法接受客戶端JavaScript使傳遞的參數,注意它是首先觸發的。接下來觸發的就是GetCallbackResult()方法,它將所得到的結果傳回給客戶端的JavaScript,JavaScript再將結果更新到頁面。
本例中的RaiseCallbackEvent()中的參數為我們在文本框的輸入信息。為了表明它是從服務器返回的,我們加了一些說明性的文字。然后用GetCallbackResult()方法中將結果傳回到客戶端。完整的頁面邏輯代碼如下:
編寫客戶端腳本
客戶端腳本主要是用來在服務器端和客戶端之間進行信息的交互,就拿本例來說,我們在前面的頁面邏輯代碼中使用了一個名為eventArgument參數,這是怎么實現參數的傳遞的呢?我們將在后面的章節進行討論,現在在頁面中添加如下的JavaScript函數代碼
我們在上述的JavaScript函數代碼引用了一個ClientScript.GetCallbackEventReference(……)方法,該方法實現的是什么功能呢?下面是摘自MSDN2上的對ClientScript.GetCallbackEventReference(……)的詳細說明。
public string GetCallbackEventReference (Control control,string argument,string clientCallback,string context)
參數:
下面是ClientScriptManager.GetCallbackEventReference 方法的重載列表
后臺代碼 CallBackExample.aspx.cs
代碼說明:
若要從客戶端成功運行服務器代碼,而不執行回發,必須在服務器頁代碼中實現合適的接口。為此我們在第12行代碼中對 ICallbackEventHandler 接口進行聲明。第15和19行創建了兩個服務器端的代碼回調方法。第15行的"RaiseCallbackEvent()"方法中的"eventArgument"字符串參數是來什么地方呢?轉到前臺頁面的第10行代碼,arg就相當于傳遞給"RaiseCallbackEvent()"方法的實參。第19行的"GetCallbackResult()"方法則將通過"RaiseCallbackEvent()"方法得到的結果返回給客戶端,即結果"result"最終被傳遞到前臺頁面的第15代碼所示的"ReceiveServerData()"方法的"result"參數中。
前臺代碼 CallBackExample.aspx
代碼說明:
為了向服務器頁發送回調和接收結果這兩個功能,我們在前臺頁面中定義了2個客戶端腳本函數。第7行所示的"CallServer()"函數實現的就是發送回調的功能,注意發送回調的函數實際是在服務器端實現的,這是因為真正實現發送回調的是第11行的"ClientScript.GetCallbackEventReference()"方法,而"CallServer()"函數只是對"ClientScript.GetCallbackEventReference()"方法的引用,并提供一些必要的參數。
現在我們來詳細講解下這些客戶端函數的具體實現細節,我們通過單擊頁面第25和26行所聲明的按鈕后,將觸發OnClick事件。
在"CallServer()"中將文本框和標簽作為參數傳遞到第7行相應的JavaScript函數后,"inputcontrol"和"context"就如同成為文本框和標簽控件形參數。第9行代碼表示沒有接受到回調結果前"context"將顯示一個"加載中……"的信息,直到回調完成后才用第17行的代碼將回調的結果用"context"重新進行顯示。第10行代碼表示將文本框的輸入值賦予"arg",并且"arg"在第12行代碼的ClientScript.GetCallbackEventReference()方法中作為對應的第2個參數。第一個參數用"this"表示對本頁面的引用,因為ClientScript.GetCallbackEventReference()方法也是在CallBackExample.aspx實現的。第三個參數表示接受回調結果的客戶端函數,它在這和第15行代碼所實現的ReceiveServerData()函數相匹配(注意函數名稱必須是一致的,否則會導致出錯),回調的結果將通過"context"進行顯示。第四個參數"context"用于從服務器端返回的上下文,因為ClientScript.GetCallbackEventReference()方法是在服務器端執行的,在該方法中原本傳遞的"context"內容為一個"加載中……"的信息,回調返回后"context"在第17行中被重新進行改寫,如果沒有對上下文的引用的話,你可以將該參數設置為"null"。
讀取數據庫信息的客戶端回調程序
本程序是一個實現讀取Northwind數據庫的Emlpoyees信息,為此你必須先保證Northwind數據庫存在。下圖是Emlpoyees表的內容。
在文本框輸入要查找的用戶名后,接著點擊"回調"按鈕就會發生客戶端回調。這是查找到用戶的顯示結果
用戶不存在的顯示信息:
后臺代碼:ClientCallbacksSimple.aspx.cs
代碼說明:在RaiseCallbackEvent()方法中,傳遞了一個從前臺頁面文本框的輸入數據作為其參數,即所要從數據庫查詢的用戶名。第28-34行代碼的功能為讀取用戶的詳細信息,并且將用戶信息保存在一個字符串strUserInfo中。如果查找不到相應的用戶,則返回一些出錯信息,見代碼36-45。GetCallbackResult()方法回發回調結果,即保存用戶信息的字符串。
前臺代碼:ClientCallbacksSimple.aspx
代碼說明:這個程序與第一個程序的最大不同就是前臺頁面上有些細微的區別。如代碼17-19所示,我們將發送回調的ClientScript.GetCallbackEventReference()方法直接寫在了按鈕的單擊事件中,這也是一種可行且簡捷的方式。ClientScript.GetCallbackEventReference()方法的3個參數為"OnCallback",表示回調完成后將回調結果返回給客戶端的OnCallback()腳本函數,在此回調結果strUserInfo將作為該函數的一個參數在頁面進行顯示,如代碼9所示。由于我們在此沒有用到上下文的聯系,所以ClientScript.GetCallbackEventReference()方法的4個參數為"null",但是OnCallback()腳本函數還是要保留該"context"參數,因為這是接受回調結果的客戶端函數的固定格式。
小結:
注意所有的異步技術如本文所探討的Callback客戶端回調,以及微軟新推出的Atlas框架,都不再使用傳統的Postback。因此客戶端在呈現由服務器端返回的數據時,瀏覽器下方將看不到一閃而過的綠色狀態條,并且異步過程只傳送和接受少量的數據,而非Postback過程中傳遞的整個ViewState狀態,因此程序在執行性能上有了較大的提高。希望讀者耐心理解和練習上述的兩個實例,只有通過自己的實踐才能理解客戶端回調的精髓。
開發人員使用JavaScript的一個主要原因就是可以避免回發過程中帶來的頁面刷新。例如我們可以根據用戶的需要使用Treeview控件來展開和折疊相應的數據節點。當你展開一個節點時,該Treeview控件將會利用JavaScript讀取服務器上的子節點信息,然后平滑無刷新地插入這些新節點。如果沒有使用JavaScript的話,Treeview控件將會因為頁面的回發而重新構建。不但用戶會發現因頁面刷新而帶來的延遲,而且頁面極有可能回復到原來的狀態,即丟失前面所展開的那些子節點信息。對于服務器端來說,因為每次回發的過程中都要處理大量的視圖狀態(View State)信息,這也會嚴重影響程序的整體執行性能。
以前我們使用的JavaScript示例幾乎都是自包含的,即它們通常是為了完成一些特殊的顯示效果(例如彈出一個新的頁面窗口),而沒有和服務器端代碼進行信息的交互。如果你也想構建一個類似的無刷新頁面的話,你首先必須調用服務器端的一個特定的方法,等待服務器響應后就會將請求的信息傳遞到客戶端,從而避免了回發這個過程。為了實現這個方案,你首先需要對如何將客戶端腳本和服務器端代碼進行通訊有個大致的了解。盡管有許多中方法可以實現這兩者間的交互(例如調用Web服務),但是由于受到特定的瀏覽器和平臺的限制,它們的實現是還是有一定的難度的。而在ASP.NET 2.0中,引入了一個稱為"客戶端回調"的功能,利用這個內建的解決方案我們可以輕松實現客戶端腳本和服務器端代碼間的交互,從而避免了頁面因回發帶來的頻繁刷新。
版權聲明:任何獲得天極網授權的網站,轉載時請務必保留作者信息和以下鏈接
天極開發ASP.NET專欄:http://dev.yesky.com/msdn/msdnasp/
客戶端回調本質上就是指通過前端的客戶端腳本向服務器端傳遞相應的數據參數,服務器端再以接受到的參數進行查詢和處理,最后將結果回傳到客戶端進行顯示。雖然這樣的過程不是一種創舉,但是對于許多開發者來說這在某種思維上還是無法理解的,因為JavaScript的內存管理和.NET CLR的內存管理是不同的進程,而且管理的空間上也截然不同,所以彼此間無法直接參照也沒有直接進行交互的方式,而客戶端回調卻是實現客戶端和服務器端進行溝通的方法之一,又因為它是在客戶端觸發的,所以這就應該是"客戶端回調"命名的由來吧!
創建一個簡單的客戶端回調
為了在ASP.NET中展示一個客戶端回調的實例,首先我們將概述客戶端回調間的交互過程是如何實現的。下面是基本的步驟:
1. 在某時刻激活一個JavaScript事件,從而觸發客戶端回調。
2. 觸發客戶端回調發生后,服務器端的一個方法將被執行。該方法有一個固定的模式――它接受的是一個字符串參數,并且返回的也是一個字符串參數。
3. 一旦頁面接受到來自服務器端方法的響應結果后,它就可以利用JavaScript修改一些和用戶界面有關的信息(例如顯示在頁面上顯示返回的結果)
對于開發人員來說,底層的交互過程是非常復雜的,ASP.NET則將交互的處理過程進行了抽象化,這樣使得開發人員可以直接建立表層的客戶端回調,而無需考慮底層的操作是如何實現的。
下面的實例中,頁面中放置了一個文本框,一個提交按鈕和一個標簽。文本框是用來接受用戶的輸入信息,在單擊提交按鈕后將把文本框中輸入的信息在標簽上進行實時的顯示。注意,在輸入信息后單擊提交按鈕時,并沒有像以前傳統的提交方式那樣重新對頁面進行構建和刷新。圖1-1為該實例的效果圖。
![]() ![]() |
創建基本的頁面
按照上圖的布局在工具欄的"標準"標簽中拖拽出一個TextBox控件,一個Label控件到主窗體上。然后在"HTML"標簽中拖拽出一個InputButton的HTML按鈕,注意,該按鈕不是我們經常使用的服務器端控件,而是一個HTML元素。在按鈕中添加一個onclick事件,點擊該按鈕這將向服務器端發出回調請求,這個onclick事件的具體實現細節將在以后的過程中加以說明。得到的初始頁面代碼如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="CallBackExample.aspx.cs" Inherits="CallBackExample" %> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>客戶端回調</title> </head> <body> <form id="form1" runat="server"> <div> 請輸入信息:<asp:TextBox ID="txtEnter" runat="server"></asp:TextBox> <input id="btnSubmit" type="button" value="提交" onclick="CallServer(txtEnter,lblShow)"/> <br /> <asp:Label ID="lblShow" runat="server"></asp:Label> </div> </form> </body> </html> |
執行回調
為了實現客戶端回調,你的頁面邏輯代碼中必須實現一個ICallbackEventHandler接口。代碼如下:
public partial class CallBackExample : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler {… …} |
ICallbackEventHandler接口定義了兩個方法,RaiseCallbackEvent()從瀏覽器接受一個字符串作為事件參數,即該方法接受客戶端JavaScript使傳遞的參數,注意它是首先觸發的。接下來觸發的就是GetCallbackResult()方法,它將所得到的結果傳回給客戶端的JavaScript,JavaScript再將結果更新到頁面。
本例中的RaiseCallbackEvent()中的參數為我們在文本框的輸入信息。為了表明它是從服務器返回的,我們加了一些說明性的文字。然后用GetCallbackResult()方法中將結果傳回到客戶端。完整的頁面邏輯代碼如下:
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class CallBackExample : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler { //定義一個字符串,回調的結果信息將保存在該字符串中 private string result; //引發回調事件處理 public void RaiseCallbackEvent(string eventArgument) { //"eventArgument"為從客戶端的JavaScript傳遞過來的參數 result = "從服務器端返回的內容:" + eventArgument; } //回傳回調結果 public string GetCallbackResult() { return result; } } |
編寫客戶端腳本
客戶端腳本主要是用來在服務器端和客戶端之間進行信息的交互,就拿本例來說,我們在前面的頁面邏輯代碼中使用了一個名為eventArgument參數,這是怎么實現參數的傳遞的呢?我們將在后面的章節進行討論,現在在頁面中添加如下的JavaScript函數代碼
function CallServer(inputcontrol,context) { //回調還沒有處理完全時其預先加載的顯示值 context.innerHTML = "加載中......"; //為你在文本框中輸入的信息,并且arg在這里就是將其值傳遞到 //RaiseCallbackEvent(String eventArgument)方法對應的eventArgument中 arg = inputcontrol.value; //獲取一個對客戶端函數的引用;調用該函數時,將啟動一個對服務器端事件的客戶端回調。 <%= ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context")%>; } |
我們在上述的JavaScript函數代碼引用了一個ClientScript.GetCallbackEventReference(……)方法,該方法實現的是什么功能呢?下面是摘自MSDN2上的對ClientScript.GetCallbackEventReference(……)的詳細說明。
public string GetCallbackEventReference (Control control,string argument,string clientCallback,string context)
參數:
參數 | 作用 |
control | 處理客戶端回調的服務器 Control。該控件必須實現 ICallbackEventHandler 接口并提供 RaiseCallbackEvent 方法。 |
argument | 從客戶端腳本傳遞一個參數到服務器端的RaiseCallbackEvent 方法。 |
clientCallback | 一個客戶端事件處理程序的名稱,該處理程序接收服務器端事件返回的結果。 |
context | 啟動回調之前在客戶端的客戶端腳本信息。腳本的結果傳回給客戶端事件處理程序。 |
返回值 | 調用客戶端回調的客戶端函數的名稱。 |
下面是ClientScriptManager.GetCallbackEventReference 方法的重載列表
名稱 | 說明 |
ClientScriptManager.GetCallbackEventReference (Control, String, String, String) | 獲取一個對客戶端函數的引用;調用該函數時,將啟動一個對服務器端事件的客戶端回調。此重載方法的客戶端函數包含指定的控件、參數、客戶端腳本和上下文。 |
ClientScriptManager.GetCallbackEventReference (Control, String, String, String, Boolean) | 獲取一個對客戶端函數的引用;調用該函數時,將啟動一個對服務器端事件的客戶端回調。此重載方法的客戶端函數包含指定的控件、參數、客戶端腳本、上下文和布爾值。 |
ClientScriptManager.GetCallbackEventReference (Control, String, String, String, String, Boolean) | 獲取一個對客戶端函數的引用;調用該函數時,將啟動一個對服務器端事件的客戶端回調。此重載方法的客戶端函數包含指定的控件、參數、客戶端腳本、上下文、錯誤處理程序和布爾值。 |
ClientScriptManager.GetCallbackEventReference (String, String, String, String, String, Boolean) | 獲取一個對客戶端函數的引用;調用該函數時,將啟動一個對服務器端事件的客戶端回調。此重載方法的客戶端函數包含指定的目標、參數、客戶端腳本、上下文、錯誤處理程序和布爾值。 我們就整個程序作個系統的說明,并且列出前臺的頁面代碼和后臺的邏輯代碼,這樣可以使得你對程序有個直觀的理解。 |
后臺代碼 CallBackExample.aspx.cs
![]() |
代碼說明:
若要從客戶端成功運行服務器代碼,而不執行回發,必須在服務器頁代碼中實現合適的接口。為此我們在第12行代碼中對 ICallbackEventHandler 接口進行聲明。第15和19行創建了兩個服務器端的代碼回調方法。第15行的"RaiseCallbackEvent()"方法中的"eventArgument"字符串參數是來什么地方呢?轉到前臺頁面的第10行代碼,arg就相當于傳遞給"RaiseCallbackEvent()"方法的實參。第19行的"GetCallbackResult()"方法則將通過"RaiseCallbackEvent()"方法得到的結果返回給客戶端,即結果"result"最終被傳遞到前臺頁面的第15代碼所示的"ReceiveServerData()"方法的"result"參數中。
前臺代碼 CallBackExample.aspx
![]() |
代碼說明:
為了向服務器頁發送回調和接收結果這兩個功能,我們在前臺頁面中定義了2個客戶端腳本函數。第7行所示的"CallServer()"函數實現的就是發送回調的功能,注意發送回調的函數實際是在服務器端實現的,這是因為真正實現發送回調的是第11行的"ClientScript.GetCallbackEventReference()"方法,而"CallServer()"函數只是對"ClientScript.GetCallbackEventReference()"方法的引用,并提供一些必要的參數。
現在我們來詳細講解下這些客戶端函數的具體實現細節,我們通過單擊頁面第25和26行所聲明的按鈕后,將觸發OnClick事件。
在"CallServer()"中將文本框和標簽作為參數傳遞到第7行相應的JavaScript函數后,"inputcontrol"和"context"就如同成為文本框和標簽控件形參數。第9行代碼表示沒有接受到回調結果前"context"將顯示一個"加載中……"的信息,直到回調完成后才用第17行的代碼將回調的結果用"context"重新進行顯示。第10行代碼表示將文本框的輸入值賦予"arg",并且"arg"在第12行代碼的ClientScript.GetCallbackEventReference()方法中作為對應的第2個參數。第一個參數用"this"表示對本頁面的引用,因為ClientScript.GetCallbackEventReference()方法也是在CallBackExample.aspx實現的。第三個參數表示接受回調結果的客戶端函數,它在這和第15行代碼所實現的ReceiveServerData()函數相匹配(注意函數名稱必須是一致的,否則會導致出錯),回調的結果將通過"context"進行顯示。第四個參數"context"用于從服務器端返回的上下文,因為ClientScript.GetCallbackEventReference()方法是在服務器端執行的,在該方法中原本傳遞的"context"內容為一個"加載中……"的信息,回調返回后"context"在第17行中被重新進行改寫,如果沒有對上下文的引用的話,你可以將該參數設置為"null"。
讀取數據庫信息的客戶端回調程序
本程序是一個實現讀取Northwind數據庫的Emlpoyees信息,為此你必須先保證Northwind數據庫存在。下圖是Emlpoyees表的內容。
![]() |
在文本框輸入要查找的用戶名后,接著點擊"回調"按鈕就會發生客戶端回調。這是查找到用戶的顯示結果
![]() |
用戶不存在的顯示信息:
![]() |
后臺代碼:ClientCallbacksSimple.aspx.cs
01 using System; 02 using System.Data; 03 using System.Configuration; 04 using System.Collections; 05 using System.Web; 06 using System.Web.Security; 07 using System.Web.UI; 08 using System.Web.UI.WebControls; 09 using System.Web.UI.WebControls.WebParts; 10 using System.Web.UI.HtmlControls; 11 using System.Data.SqlClient; 12 public partial class ClientCallbacksSimple : System.Web.UI.Page, 13 13 System.Web.UI.ICallbackEventHandler 14 { 15 protected string strUserInfo; //保存讀取的用戶信息 16 //引發回調事件 17 public void RaiseCallbackEvent(string txtFirstName) 18 { 19 if (txtFirstName != null) 20 { 21 SqlConnection conn = new SqlConnection("data source=localhost;initial 22 catalog=Northwind;integrated security=SSPI"); 23 conn.Open(); 24 SqlCommand cmd = new SqlCommand("select EmployeeID,FirstName,City,Address 25 25 from Employees where FirstName=@FirstName", conn); 26 cmd.Parameters.Add("@FirstName", SqlDbType.NVarChar, 10).Value = txtFirstName; 27 SqlDataReader dr = cmd.ExecuteReader(); 28 if (dr.Read()) 29 { 30 strUserInfo = "員工代號:" + dr["EmployeeID"] + ""; 31 strUserInfo += "姓名:" + dr["FirstName"] + ""; 32 strUserInfo += "居住城市:" + dr["City"] + ""; 33 strUserInfo += "地址:" + dr["Address"].ToString().Replace("","")+ ""; 34 strUserInfo += "服務器查詢時間:" + DateTime.Now.ToLongTimeString(); 35 } 36 else 37 { 38 if (String.IsNullOrEmpty(txtFirstName)) 39 { 40 strUserInfo = "請輸入姓名"; 41 } 42 else 43 { 44 strUserInfo = "查無此人"; 45 } 46 } 47 cmd.Dispose(); 48 dr.Dispose(); 49 conn.Dispose(); 50 } 51 } 52 //回傳回調結果 53 public string GetCallbackResult() 54 { 55 return strUserInfo; //回傳員工的基本信息 56 } 57 } |
代碼說明:在RaiseCallbackEvent()方法中,傳遞了一個從前臺頁面文本框的輸入數據作為其參數,即所要從數據庫查詢的用戶名。第28-34行代碼的功能為讀取用戶的詳細信息,并且將用戶信息保存在一個字符串strUserInfo中。如果查找不到相應的用戶,則返回一些出錯信息,見代碼36-45。GetCallbackResult()方法回發回調結果,即保存用戶信息的字符串。
前臺代碼:ClientCallbacksSimple.aspx
01 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="ClientCallbacksSimple.aspx.cs" 02 Inherits="ClientCallbacksSimple" %> 03 <html xmlns="http://www.w3.org/1999/xhtml" > 04 <head runat="server"> 05 <title>讀取數據庫信息的客戶端回調程序</title> 06 <script type="text/JavaScript"> 07 function OnCallback(strUserInfo,context) 08 { 09 Results.innerText = strUserInfo; 10 } 11 </script> 12 </head> 13 <body> 14 <form id="form1" runat="server"> 15 <div> 16 姓名:<input id="txtUserName" type="text" /> 17 <input id="btnCallback" type="button" value="回調" onclick="<%= 18 ClientScript.GetCallbackEventReference(this,"document.form1.txtUserName.value", 19 "OnCallback",null) %>" /> 20 <br /> 21 <div ID="Results" style="background-color: pink"></div> 22 </div> 23 </form> 24 </body> 25 </html> |
代碼說明:這個程序與第一個程序的最大不同就是前臺頁面上有些細微的區別。如代碼17-19所示,我們將發送回調的ClientScript.GetCallbackEventReference()方法直接寫在了按鈕的單擊事件中,這也是一種可行且簡捷的方式。ClientScript.GetCallbackEventReference()方法的3個參數為"OnCallback",表示回調完成后將回調結果返回給客戶端的OnCallback()腳本函數,在此回調結果strUserInfo將作為該函數的一個參數在頁面進行顯示,如代碼9所示。由于我們在此沒有用到上下文的聯系,所以ClientScript.GetCallbackEventReference()方法的4個參數為"null",但是OnCallback()腳本函數還是要保留該"context"參數,因為這是接受回調結果的客戶端函數的固定格式。
小結:
注意所有的異步技術如本文所探討的Callback客戶端回調,以及微軟新推出的Atlas框架,都不再使用傳統的Postback。因此客戶端在呈現由服務器端返回的數據時,瀏覽器下方將看不到一閃而過的綠色狀態條,并且異步過程只傳送和接受少量的數據,而非Postback過程中傳遞的整個ViewState狀態,因此程序在執行性能上有了較大的提高。希望讀者耐心理解和練習上述的兩個實例,只有通過自己的實踐才能理解客戶端回調的精髓。