在期望不執行回傳(postback)而從用戶端運行伺服器代碼的情況下,可以使用ClientScriptManager類來調用用戶端回調(callback)。這稱為對伺服器執行帶外回調。在用戶端回調中,用戶端指令碼函數項ASP.NET網頁發送非同步請求。網頁修改其正常生命週期來處理回調。
回調的過程如下: (1)用戶端發出請求,請求內容包括:指定更新控制項和傳遞參數。 (2)服務端響應、處理。 (3)伺服器將處理後的內容以字串返回。 (4)用戶端指定一個函數接受傳回值。 (5)用戶端更新指定控制項。 使用回調的步驟如下: (1)在控制項或page類中實現ICallbackEventHandler介面。該介面有兩個方法,分別是RaiseCallbackEvent和GetCallbackResult。RaiseCallbackEvent方法是回調執行的方法,該方法處理回調的內容。它沒有傳回值,而是從瀏覽器接受一個字串作為事件的參數,即該方法接受用戶端JavaScript所傳遞的參數。注意它是首先觸發的。接下來觸發的就是GetCallbackResult方法,它將所得到的結果傳回給用戶端的指令碼。 (2)產生調用該回調的用戶端指令碼。可以通過ClientScriptManager類的GetCallbackEventReference方法來產生。 (3)編寫代碼調用(2)中產生的用戶端指令碼。 以下通過一個例子來說明回調過程。。。 建立一ASP.NET 應用程式,設定Default表單介面如下: 1,在Defalut.aspx.cs類實現ICallbackEventHandler介面,代碼如下public partial class _Default : System.Web.UI.Page,ICallbackEventHandler
{
string callbackResult;
#region ICallbackEventHandler 成員
//這是RaiseCallbackEvent方法觸發之後觸發的,它將得到的結果返回給用戶端的指令碼《《《《《《《《222222
//用戶端指令碼的onCallbackComplete(result,context)方法裡面的result在這裡其實就是指callbackResult
public string GetCallbackResult()
{
return callbackResult;
}
//回調執行的方法,首先觸發的,裡面的一個參數接受從用戶端傳來的值《《《《《《1111111
public void RaiseCallbackEvent(string eventArgument)
{
try
{
callbackResult = WebService.getResult(eventArgument);//由於這裡調用的是webservice的getResult的方法,所以也可以把getResult方法放在這裡。
}
catch (Exception e)
{
Trace.Write(e.Message);
throw new Exception("調用失敗");
}
}
#endregion
} 2,產生調用該回調的用戶端指令碼。在Default類的page_Load事件中加入如下代碼:public partial class _Default : System.Web.UI.Page,ICallbackEventHandler
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsCallback)
{
return;
}
//根據傳入的參數返回實際的回調指令碼《《《《《《《《33333333
//target處理用戶端回調的伺服器 Control 的名稱。該控制項必須實現 ICallbackEventHandler 介面並提供 RaiseCallbackEvent 方法。
//argument從用戶端指令碼傳遞給伺服器端的一個參數
//clientCallback一個用戶端事件處理常式的名稱,該處理常式接收成功的伺服器端事件的結果。
//context啟動回調之前在用戶端計算的用戶端指令碼。指令碼的結果傳回用戶端事件處理常式。
//clientErrorCallback用戶端事件處理常式的名稱,該處理常式在伺服器端事件處理常式出現錯誤時接收結果。
//useAsynctrue 表示同步執行回調;false 表示非同步執行回調。
string callBackFunctionCall = ClientScript.GetCallbackEventReference(this, "getTextValue()", "onCallbackComplete", null, "onCallbackError", true);
//註冊用戶端指令碼《《《《《《《《444444
string csname = "CallBack";//要註冊的用戶端指令碼的鍵。
if (!ClientScript.IsClientScriptBlockRegistered(GetType(), csname))
{
//type要註冊的用戶端指令碼的類型。
//key要註冊的用戶端指令碼的鍵。
//script要註冊的用戶端指令碼文本。
//addScriptTags指示是否添加指令碼標記的布爾值。
ClientScript.RegisterClientScriptBlock(GetType(), csname, "function DoClientCallBack(){" + callBackFunctionCall + "}", true);
}
}
} 3,編寫用戶端代碼,在Default.aspx檔案中添加如下JavaScript指令碼:<script type ="text/javascript" >
function getTextValue()//要傳遞給伺服器的參數
{
var arg1=document.getElementById ("Text1").value;
var arg2=document.getElementById ("Text2").value;
var arg="argA="+arg1+"&argB="+arg2;//注意這裡的傳遞方式
return arg;
}
function onCallbackComplete(result,context)//回調成功
{
// alert(result);
document.getElementById ("TextArea1").value=result;
}
function onCallbackError()//回調失敗
{
alert("回調失敗!");
}
</script> 最後補充在(1)中的RaiseCallbackEvent方法中調用的類webservice的getResult方法,在項目中添加一名為WebService.asmx的web服務頁面。在WebService.asmx.cs檔案中定義一個名為getResult的方法,這段代碼其實也可以直接放置在RaiseCallbackEvent方法中,但是為了實現調用webservice的效果還是把它單獨放置到一個webservice檔案中,具體代碼如下:public class WebService : System.Web.Services.WebService
{
[WebMethod]
public static string getResult(string name)//靜待函數
{
string[] keyValuePairs;//含有”=“的數組
string[] keyValue;//只有字串的數組
NameValueCollection m_queryString= new NameValueCollection();//索引值對的集合
keyValuePairs = name.Split("&".ToCharArray ());
if (keyValuePairs.Length > 0)//如果傳遞的參數是argA=arg1&argB=arg2……形式的,也就是說參數不止一個
{
for (int i = 0; i < keyValuePairs.Length; i++)
{
keyValue = keyValuePairs.GetValue(i).ToString().Split("=".ToCharArray());
m_queryString.Add(keyValue[0], keyValue[1]);
}
}
else//傳遞的參數只有一個
{
keyValue = name.Split("=".ToCharArray());
if (keyValue.Length > 0)//如果有參數傳遞過來的話
{
m_queryString.Add(keyValue[0], keyValue[1]);
}
}
//通過htQueryString["argA"]這種方式調用參數的值
return "第一個參數是: " + m_queryString["argA"].ToString() + "\n第二個參數是: " + m_queryString["argB"].ToString();
}
}執行結果如下:該頁面的使用者互動與上一篇部落格Ajax開啟三種頁面的請求的頁面是一樣的,但是代碼大大減少了,因為我們不需要編寫代碼來解析XML或處理XMLHttpRequest對象。