在 ASP.NET 網頁中以程式設計方式實作用戶端回呼但不回傳
更新:2007 年 11 月
在 ASP.NET Web 網頁的預設模型中,使用者會與網頁互動並且按下按鈕,或執行其他動作以產生回傳。就會重新建立網頁和控制項、在伺服器上執行網頁程式碼,然後將新版本的網頁呈現至瀏覽器。然而在某些情形下,在不執行回傳的情況下從用戶端執行伺服端程式碼是很有用的。如果網頁中的用戶端指令碼是維護某些狀態資訊 (例如,區域變數值),則張貼網頁並且取得新複本會摧毀該狀態。此外,網頁回傳會產生降低效能的處理負載,強迫使用者等待處理和重新建立網頁。
若要避免遺失用戶端狀態以及伺服器來回往返所帶來的處理負載,您可以撰寫能夠執行用戶端回呼的 ASP.NET Web 網頁程式碼。在用戶端回呼中,用戶端指令碼函式會將要求傳送至 ASP.NET Web 網頁。此網頁會執行其一般生命週期的修改版本。網頁會進行初始化並且建立其控制項與其他成員,然後叫用特殊標記的方法。方法會執行您編碼的處理,然後將其他用戶端指令碼函式能夠讀取的值傳回瀏覽器。在整個程序中,網頁會存在瀏覽器內。
有幾種 Web 伺服器控制項會使用用戶端回呼。例如,TreeView 控制項會使用用戶端回呼實作視需要填入 (Populate-On-Demand) 的功能。如需詳細資訊,請參閱 TreeView Web 伺服器控制項概觀。
有數個選項可以自動化 ASP.NET Web 網頁中的用戶端回呼。ASP.NET 中的 AJAX 功能 (例如 UpdatePanel 伺服器控制項) 可以為您自動化非同步部分網頁更新,而 Web 服務通訊功能則可以自動化非同步 Web 服務呼叫。
如需 ASP.NET 中能為您自動化用戶端回呼的 AJAX 功能概觀,請參閱下列主題:
您也可以撰寫自己的用戶端指令碼,直接實作用戶端回呼。本主題討論如何針對用戶端與伺服器之間的非同步通訊實作自己的用戶端回呼。
用戶端回呼的元件
建立以程式設計方式實作用戶端回呼的 ASP.NET 網頁與建立任何 ASP.NET 網頁很類似,其中只有下列幾項差異。網頁的伺服器程式碼必須執行下列工作:
實作 ICallbackEventHandler 介面。您可以將這個介面宣告加入任何 ASP.NET Web 網頁
提供 RaiseCallbackEvent 方法的實作。這個方法會被叫用,以便在伺服器上執行回呼。
提供 GetCallbackResult 方法的實作。這個方法會將回呼結果傳回給用戶端。
此外,網頁必須包含執行下列動作的三個用戶端指令碼函式:
一個函式呼叫執行伺服器實際要求的 Helper 方法。您可以使用此函式來執行自訂邏輯,以便先準備好事件引數。您可以將字串當做參數,傳送至伺服器端的回呼事件處理常式。
另一個函式會接收 (被呼叫) 處理回呼事件的伺服端程式碼結果,接受代表結果的字串。這就稱為用戶端回呼函式。
第三個函式則是可對伺服器執行實際要求的 Helper 函式。當您在伺服器程式碼中使用 GetCallbackEventReference 方法來產生此函式的參考時,ASP.NET 會自動產生此函式。
用戶端回呼和回傳都是對原始網頁的要求。因此,用戶端回呼和回傳都會被當成網頁要求記錄在 Web 伺服器記錄中。
在伺服端程式碼中實作必要的介面
若要在不執行回傳的情況下,從用戶端指令碼執行伺服端程式碼,您就必須在伺服端程式碼中實作幾項介面。
宣告 ICallbackEventHandler 介面
您可以在網頁類別宣告中宣告 ICallbackEventHandler 介面。如果您建立程式碼後置網頁,就可以使用像是下列的語法宣告介面。
Partial Class CallBack_DB_aspx
Inherits System.Web.UI.Page
Implements System.Web.UI.ICallbackEventHandler
public partial class CallBack_DB_aspx :
System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
如果您使用單一檔案網頁或使用者控制項,可以使用網頁中的 @ Implements 指示詞加入宣告,如下列範例所示:
<%@ Page Language="VB" %>
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
<%@ Page Language="C#" %>
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
注意事項: |
---|
介面名稱需區分大小寫。 |
建立伺服器回呼方法
在伺服端程式碼中,您必須建立實作 RaiseCallbackEvent 方法的方法,以及實作 GetCallbackResult 方法的方法。RaiseCallbackEvent 方法會採用單一字串引數,而不是通常搭配事件處理常式使用的兩個引數。所以方法的其中一部分看起來可能會像下列範例所示:
Public Sub RaiseCallbackEvent(ByVal eventArgument As String) _
Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
End Sub
public void RaiseCallbackEvent(String eventArgument)
{
}
GetCallbackResult 方法不會採用任何引數,而且會傳回字串。所以方法的其中一部分看起來可能會像下列範例所示:
Public Function GetCallbackResult() As String Implements _
System.Web.UI.ICallbackEventHandler.GetCallbackResult
Return aStringValue
End Function
public string GetCallbackResult()
{
return aStringValue;
}
建立用戶端指令碼函式
您必須將用戶端指令碼函式加入網頁以便執行兩項功能:將回呼傳送至伺服器網頁以及接受結果。兩種用戶端指令碼函式都是以 ECMAScript (JavaScript) 撰寫。
傳送回呼
在伺服端程式碼中會產生傳送回呼的函式。實際回呼是由實作 ICallbackEventHandler 介面的任何網頁,都能使用的程式庫函式執行。您可以取得程式庫函式的參考,方法是呼叫網頁的 GetCallbackEventReference 方法,而此方法可透過網頁的 ClientScript 屬性存取。然後可以動態方式建置用戶端函式,以包含對來自 GetCallbackEventReference 方法回傳值的呼叫。您會將網頁的參考 (在 C# 是 this 而在 Visual Basic 是 Me)、將用來傳遞資料的引數名稱、將接收回呼資料的用戶端指令碼函式名稱,以及傳遞任何所需內容的引數傳遞給這個方法。
當您完成建置這個函式時,可以呼叫 RegisterClientScriptBlock 方法將其插入網頁中。
下列範例示範如何動態建立名為 CallServer 的函式,以便叫用回呼。
Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
Dim cm As ClientScriptManager = Page.ClientScript
Dim cbReference As String
cbReference = cm.GetCallbackEventReference(Me, "arg", _
"ReceiveServerData", "")
Dim callbackScript As String = ""
callbackScript &= "function CallServer(arg, context)" & _
"{" & cbReference & "; }"
cm.RegisterClientScriptBlock(Me.GetType(), _
"CallServer", callbackScript, True)End Sub
void Page_Load(object sender, EventArgs e)
{
ClientScriptManager cm = Page.ClientScript;
String cbReference = cm.GetCallbackEventReference(this, "arg",
"ReceiveServerData", "");
String callbackScript = "function CallServer(arg, context) {" +
cbReference + "; }";
cm.RegisterClientScriptBlock(this.GetType(),
"CallServer", callbackScript, true);
}
您所產生之函式接受的引數名稱必須符合傳遞給 GetCallbackEventReference 方法的值名稱。
下列範例將示範可用來叫用回呼並處理其傳回值的某些標記:
<input type="button" value="Callback"
onclick="CallServer(1, alert('Callback'))"/>
<br />
<span id="Message"></span>
<input type="button" value="Callback"
onclick="CallServer(1, alert('Callback'))"/>
<br />
<span id="Message"></span>
接收回呼
您可以撰寫在網頁中以靜態方式接收回呼的用戶端函式。函式的名稱必須符合在呼叫中傳遞給 GetCallbackEventReference 方法的名稱。接收函式會接受兩種字串值:其中之一針對回傳值,選擇性的第二個值是針對伺服器傳回的內容值。
此函式看起來如下列範例所示:
<script type="text/javascript">
function ReceiveServerData(arg, context)
{
Message.innerText = 'Processed callback.';
}
</script>