ASP.NET 2.0 引入「客戶端回呼」功能,讓瀏覽器端 JavaScript 直接呼叫伺服器端方法並接收回傳資料,無需完整回傳,避免頁面閃爍、ViewState 傳輸開銷與狀態遺失。本文深入解析實作流程、ICallbackEventHandler 介面、ClientScriptManager 輔助方法與完整範例。
WebForm_DoCallback(由 ASP.NET 自動產生),傳遞參數字串給伺服器。ICallbackEventHandler.RaiseCallbackEvent 接收參數,執行邏輯,回傳結果字串。public partial class CallbackDemo : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
{
private string _callbackResult;
// 介面方法:接收客戶端參數,執行邏輯,設定回傳結果
public void RaiseCallbackEvent(string eventArgument)
{
// eventArgument 為客戶端傳遞的字串參數
// 執行查詢、計算、驗證等邏輯
_callbackResult = $"伺服器處理時間:{DateTime.Now:HH:mm:ss},收到參數:{eventArgument}";
}
// 介面方法:回傳結果字串給客戶端
public string GetCallbackResult()
{
return _callbackResult;
}
protected void Page_Load(object sender, EventArgs e)
{
// 向頁面註冊客戶端回呼參考腳本
string callbackRef = ClientScript.GetCallbackEventReference(
this, // 目標控制項(實作 ICallbackEventHandler)
"arg", // 客戶端參數變數名稱
"ReceiveServerData", // 客戶端回呼函式名稱
"context", // 內容變數(可選)
"OnCallbackError", // 錯誤處理函式(可選)
true // 非同步呼叫
);
// 將回呼參考嵌入頁面供 JavaScript 呼叫
string script = $"function CallServer(arg, context) {{ {callbackRef}; }}";
ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", script, true);
}
}
<script type="text/javascript">
// 觸發回呼:使用者點擊按鈕
function CallServer() {
var param = document.getElementById("txtInput").value;
CallServer(param, ""); // 呼叫註冊的回呼函式
}
// 接收伺服器回傳結果
function ReceiveServerData(result, context) {
document.getElementById("lblResult").innerText = result;
}
// 錯誤處理
function OnCallbackError(error, context) {
alert("回呼錯誤:" + error.message);
}
</script>
<input type="text" id="txtInput" />
<input type="button" value="呼叫伺服器" onclick="CallServer()" />
<br />
結果:<span id="lblResult"></span>
| 方法 | 用途 |
|---|---|
GetCallbackEventReference(target, argument, clientCallback, context, errorCallback, useAsync) | 產生客戶端呼叫伺服器回呼的 JavaScript 程式碼片段 |
RegisterClientScriptBlock(type, key, script, addScriptTags) | 註冊客戶端腳本區塊 |
RegisterStartupScript(type, key, script, addScriptTags) | 註冊頁面載入完成後執行的腳本 |
IsClientScriptBlockRegistered(key)/IsStartupScriptRegistered(key) | 檢查腳本是否已註冊,避免重複 |
target:實作 ICallbackEventHandler 的控制項(通常為 this 頁面或自訂控制項)。argument:客戶端參數變數名稱,對應 RaiseCallbackEvent(string eventArgument)。clientCallback:成功回呼的 JavaScript 函式名稱,簽章 function(result, context)。context:可選內容變數名稱,原樣傳回回呼函式。errorCallback:可選錯誤處理函式名稱,簽章 function(error, context)。useAsync:true 使用非同步 XMLHTTP,false 同步(阻塞瀏覽器)。<%@ Page Language="C#" Async="true" %>
Async="true" 啟用非同步頁面處理管線,配合 useAsync=true 達成真正非阻塞回呼。
public class CallbackControl : WebControl, ICallbackEventHandler
{
// 同頁面實作模式...
protected override void Render(HtmlTextWriter writer)
{
// 註冊回呼腳本並輸出控制項 HTML
string callbackRef = Page.ClientScript.GetCallbackEventReference(this, "arg", "OnResult", "ctx", "OnError", true);
string script = $"function CallServer(arg, ctx) {{ {callbackRef}; }}";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "CallbackScript", script, true);
writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
writer.RenderBeginTag(HtmlTextWriterTag.Div);
writer.Write("回呼控制項內容");
writer.RenderEndTag();
}
}
| 優點 | 缺點 |
|---|---|
| 無完整回傳,體驗流暢 | 僅支援字串參數/回傳,複雜物件需序列化(JSON) |
| ViewState 不傳輸,頻寬省 | 不觸發頁面生命週期事件(Load/PreRender 等) |
| 伺服器邏輯集中,安全 | 需自行處理驗證、錯誤、狀態同步 |
| 內建機制,無需額外庫 | 較 AJAX.NET/UpdatePanel 彈性較低 |
適用:簡單查詢、驗證、計算、自動完成、即時檢查。不適用:複雜 UI 更新、大量資料綁定、需完整生命週期的操作。
UpdatePanel:部分頁面回傳,保留完整生命週期、ViewState、驗證,開發簡單但傳輸量大。客戶端回呼是 ASP.NET 2.0 邁向 AJAX 體驗的關鍵基礎設施,掌握其運作機制有助於在適當場景選擇最佳輕量化互動方案。