頁面實作 `ICallbackEventHandler`,透過 `eventArgument` 字串攜帶「動作類型」與「參數」,伺服器端解析分派至對應處理方法。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MultiCallback.aspx.cs" Inherits="Demo.MultiCallback" %>
多事件回調
using System;
using System.Web.UI;
public partial class MultiCallback : Page, ICallbackEventHandler
{
private string _callbackResult;
protected void Page_Load(object sender, EventArgs e)
{
// 註冊客戶端回調腳本
string cbRef = ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");
string script = $"function CallServer(arg, context) {{ {cbRef} }};";
ClientScript.RegisterStartupScript(GetType(), "MultiCallback", script, true);
}
// ICallbackEventHandler 實作
public void RaiseCallbackEvent(string eventArgument)
{
// 解析參數: action=Dog&name=Lucky
var args = ParseArgs(eventArgument);
string action = args["action"];
string name = args["name"];
switch (action)
{
case "Dog":
_callbackResult = $"action=Dog&msg=汪汪!{name} 正在搖尾巴~";
break;
case "Rabbit":
_callbackResult = $"action=Rabbit&msg=蹦蹦跳跳!{name} 吃紅蘿蔔~";
break;
default:
_callbackResult = "action=Error&msg=未知動作";
break;
}
}
public string GetCallbackResult() => _callbackResult;
// 簡易參數解析
private System.Collections.Generic.Dictionary ParseArgs(string argStr)
{
var dict = new System.Collections.Generic.Dictionary();
if (string.IsNullOrEmpty(argStr)) return dict;
foreach (string kv in argStr.Split('&'))
{
string[] p = kv.Split('=');
if (p.Length == 2) dict[p[0]] = System.Web.HttpUtility.UrlDecode(p[1]);
else if (p.Length == 1) dict[p[0]] = "";
}
return dict;
}
}
| 技術 | 說明 |
|---|---|
| ICallbackEventHandler | 標記頁面/控制項可接收客戶端回調 |
| GetCallbackEventReference | 產生 `__doCallback` 呼叫代碼,含 `__CALLBACKID`、`__CALLBACKPARAM` |
| 參數序列化 | `action=Dog&name=xxx` 格式,客戶端/伺服器端對稱解析 |
| RegisterStartupScript | 註冊 `CallServer` 全域函數,供前端按鈕 onclick 呼叫 |
| ReceiveServerData | 客戶端回調函數,接收伺服器端 `GetCallbackResult` 回傳字串 |
| 優點 | 缺點 |
|---|---|
| 無需 UpdatePanel/ScriptManager,輕量 | 僅支援字串參數/回傳,複雜物件需自行序列化 |
| 完整頁面生命週期 (可存取 ViewState/Session) | 仍執行完整管線,效能不如 Web API/Handler | IE6+ 相容性好 | 錯誤處理、逾時、並發控制需自行實作 |
`ICallbackEventHandler` 是 ASP.NET 2.0 時代實現「單頁多動作無刷新」的標準方式,透過 `action` 參數路由分派邏輯。雖已被現代架構取代,但在維護舊系統、受限環境 (無法引入新框架) 時仍具實用價值。