當然,我們不希望僅僅用這種強大的能力來警告用戶。這就是所有客戶端代理(如JavaScript Sample.ServerSideAd函數)還接受其他特性的原因。這種特性就是為了處理響應而調用的回調函數:
Sample.ServerSideAdd(100,99, ServerSideAdd_CallBack);
function ServerSideAdd_CallBack(response){
if (response.error != null){
alert(response.error);
return;
}
alert(response.value);
}
從上述代碼中可以看到我們指定了另外一個參數。ServerSideAdd_CallBack(同樣參見上述代碼)是用於處理服務器響應的客戶端函數。這個回調函數接收一個響應對象,該對象公開了三個主要性質
Value——服務器端函數實際返回的值(無論是字符串、自定義對象還是數據集)。
Error——錯誤消息,如果有的話。
Request——XML http請求的原始響應。
Context——上下文對象。
首先我們檢查error只看看是否出現了錯誤。通過在服務器端函數中拋出異常,可以很容易處理error特性。在這個簡化的例子中,然後用這個值警告用戶。Request特性可用於獲得更多信息。
處理類型
返回復雜類型
AJax包裝器不僅能處理ServerSideAdd函數所返回的整數。它目前還支持integers、strings、double、booleans、DateTime、DataSets和DataTables,以及自定義類和數組等基本類型。其他所有類型都返回它們的ToString值。
返回的DataSets和真正的.Net DataSet差不多。假設一個服務器端函數返回DataSet,我們可以通過下面的代碼在客戶端顯示其中的內容:
AJax還可以返回自定義類,唯一的要求是必須用Serializable屬性標記。假設有如下的類:
[Serializable()]
public class User{
private int _userId;
private string _firstName;
private string _lastName;
public int userId{
get { return _userId; }
}
public string FirstName{
get { return _firstName; }
}
public string LastName{
get { return _lastName; }
}
public User(int _userId, string _firstName, string _lastName){
this._userId = _userId;
this._firstName = _firstName;
this._lastName = _lastName;
}
public User(){}
[AJaxMethod()]
public static User GetUser(int userId){
//Replace this with a DB hit or something :)
return new User(userId,"Michael", "Schwarz");
}
}
我們可以通過調用RegisterTypeForAJax注冊GetUser代理:
private void Page_Load(object sender, EventArgs e){
Utility.RegisterTypeForAJax(typeof(User));
}
這樣就可以在客戶端異步調用GetUser:
響應中返回的值實際上是一個對象,公開了和服務器端對象相同的屬性(FirstName、LastName和UserId)。
自定義轉換器
我們已經看到,Ajax .NET包裝器能夠處理很多不同的.NET類型。但是除了大量.NET類和內建類型以外,包裝器對不能正確返回的其他類型僅僅調用ToString()。為了避免這種情況,AJax .Net包裝器允許開發人員創建對象轉換器,用於在服務器和客戶機之間平滑傳遞復雜對象。
其他事項
在其他類中注冊函數
上面的例子中,我們的服務器端函數都放在執行頁面背後的代碼中。但是,沒有理由不能把這些函數放在單獨的類文件中。要記住,包裝器的工作方式是在指定類中發現所有帶Ajax.AjaxMethod的方法。需要的類通過第二個腳本標簽指定。使用Ajax.Utility.RegisterTypeForAJax,我們可以指定需要的任何類。比如,將我們的服務器端函數作為單獨的類是合情合理的:
Public Class AJaxFunctions
_
Public Function Validate(username As String, passWord As String) As Boolean
'do something
'Return something
End Function
End Class
通過指定類的類型而不是頁面就可以讓AJax包裝器創建代理:
private void Page_Load(object sender, EventArgs e){
Ajax.Utility.RegisterTypeForAjax(typeof(AJaxFunctions));
//...
}
要記住,客戶端代理的名稱是
代理到底是如何工作的
Ajax工具生成的第二個腳本標簽(也可以手工插入)傳遞了頁面的名稱空間、類名和程序集。根據這些信息,Ajax.PageHandlerFactory就能夠使用反射得到具有特定屬性的任何函數的詳細信息。顯然,處理函數查找具有AjaxMethod屬性的函數並得到它們的簽名(返回類型、名稱和參數),從能夠創建必要的客戶端代理。具體而言,包裝器創建一個和類同名的Javascript對象,該對象提供代理。換句話說,給定一個帶有Ajax ServerSideAdd方法的服務器端類AjaxFunctions,我們就會得到公開ServerSideAdd函數的AJaxFunction JavaScript對象。如果將浏覽器指向第二個腳本標簽的路徑就會看到這種動作。