附錄
0、它是如何工作的
利用 Ajax包裝器,ASP.NET開發人員可以快速方便的部署很容易利用AJAX功能的頁面。
Ajax依靠代理(broker)指派和處理往返服務器的請求,對此,包裝器的目的是隱藏 XmlHttpRequest對象的實現,包裝器本身通過將.NET函數標記為 Ajax方法來工作。標記之后,AJAX就創建對應的JavaScript函數,這些函數(和任何JavaScript函數一樣)作為代理可以在客戶端使用 XmlHttpRequest調用。這些代理再映射回服務器端函數。
假設有一個.NET函數:
|
1
2
3
|
ublic
int
Add(
int
firstNumber,
int
secondNumber)
{
return
firstNumber + secondNumber;
}
|
包裝器將自動創建名為“Add”、帶有兩個參數的JavaScript函數。使用JavaScript(在客戶機上)調用該函數時,請求將傳遞給服務器並把結果返回給客戶機。
1、創建服務器端函數
⑴、項目中引用 Ajax.dll文件。
⑵、編寫函數代碼
|
1
2
3
4
5
6
7
8
9
10
|
namespace
ForAjax
{
public
class
Example
{
[Ajax.AjaxMethod()]
public
static
int
ServerSideAdd(
int
firstNumber,
int
secondNumber)
{
return
firstNumber + secondNumber;
}
}
}
|
函數中包含 [Ajax.AjaxMethod()]屬性集。該屬性告訴包裝器這些方法創建javaScript代理,以便在客戶端調用。
2、客戶端調用
⑴、網站中引用 Ajax.dll及 服務器項目文件。
⑵、web.config中建立HttpHandler
|
1
2
3
4
5
6
|
<
configuration
>
<
system.web
>
<
httpHandlers
>
<
add
verb
=
"POST,GET"
path
=
"ajax/*.ashx"
type
=
"Ajax.PageHandlerFactory, Ajax"
/>
</
httpHandlers
>
</
system.web
>
</
configuration
>
|
注:在 IIS7上部署。
|
1
2
3
4
|
<
system.webServer
>
<
handlers
>
<
add
name
=
"ajax"
verb
=
"POST,GET"
path
=
"ajax/*.ashx"
type
=
"Ajax.PageHandlerFactory, Ajax"
/>
</
handlers
>
</
system.webServer
>
|
⑶、客戶端頁面調用
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<%@ Page Language=
"C#"
AutoEventWireup=
"true"
CodeFile=
"Default.aspx.cs"
Inherits=
"_Default"
%>
<html>
<head>
<script language=
"javascript"
src=
"ajax/common.ashx"
></script>
<script language=
"javascript"
src=
"ajax/ForAjax.Example,ForAjax.ashx"
></script>
<script language=
"javascript"
>
var response = Example.ServerSideAdd(100,99);
alert(response.value);
</script>
</head>
<body">
<form id=
"form1"
>
</form>
</body>
</html>
|
其中,"ajax/ForAjax.Example,ForAjax.ashx" 為 "ajax/Namespace.PageClass,AssemblyName.ashx"格式。可以在瀏覽器中手工導航到src路徑(查看源代碼,復制粘貼路徑)檢查是否一切正常。
通過 web.config,我們已經保證所有對 ajax/*.ashx的請求都由自定義的 Ajax包裝器處理。包裝器負責創建帶有兩個參數的 JavaScript函數 Sample.ServerSideAdd以供前台調用。
3、回調函數
|
1
2
3
4
5
6
7
8
9
|
Sample.ServerSideAdd(100,99, ServerSideAdd_CallBack);
function
ServerSideAdd_CallBack(response){
if
(response.error !=
null
){
alert(response.error);
return
;
}
alert(response.value);
}
|
其中響應對象 response公開了三個主要性質
- Value——服務器端函數實際返回的值(無論是字符串、自定義對象還是數據集)。
- Error——錯誤消息,如果有的話。
- Request——xml http請求的原始響應。
- Context——上下文對象。
4、處理類型
Ajax包裝器不僅能處理ServerSideAdd函數所返回的整數。它目前支持 integers、strings、double、booleans、DateTime、DataSets和DataTables,以及自定義類和數組等基本類型。其他所有類型都返回它們的ToString值。
⑴、返回的 DataSets
和真正的.NET DataSet差不多。假設一個服務器端函數返回DataSet,我們可以通過下面的代碼在客戶端顯示其中的內容:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<script language=
"JavaScript"
>
//Asynchronous call to the mythical "GetDataSet" server-side
function
function
getDataSet(){
AjaxFunctions.GetDataSet(GetDataSet_callback);
}
function
GetDataSet_callback(response){
var
ds = response.value;
if
(ds !=
null
&&
typeof
(ds) ==
"object"
&& ds.Tables !=
null
){
var
s =
new
Array();
s[s.length] =
"<table border=1>"
;
for
(
var
i=0; i<ds.Tables[0].Rows.length; i++){
s[s.length] =
"<tr>"
;
s[s.length] =
"<td>"
+ ds.Tables[0].Rows[i].FirstName +
"</td>"
;
s[s.length] =
"<td>"
+ ds.Tables[0].Rows[i].Birthday +
"</td>"
;
s[s.length] =
"</tr>"
;
}
s[s.length] =
"</table>"
;
tableDisplay.innerHTML = s.join(
""
);
}
else
{
alert(
"Error. [3001] "
+ response.request.responseText);
}
}
</script>
|
⑵、返回自定義類
Ajax還可以返回自定義類,唯一的要求是必須用 [Serializable()]屬性標記。假設有如下的類:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
[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代理:
|
1
2
3
|
private
void
Page_Load(
object
sender, EventArgs e)
{
Utility.RegisterTypeForAjax(
typeof
(User));
}
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<script language=
"javascript"
>
function
getUser(userId){
User.GetUser(GetUser_callback);
}
function
GetUser_callback(response){
if
(response !=
null
&& response.value !=
null
){
var
user = response.value;
if
(
typeof
(user) ==
"object"
){
alert(user.FirstName +
" "
+ user.LastName);
}
}
}
getUser(1);
</script>
|
響應中返回的值實際上是一個對象,公開了和服務器端對象相同的屬性(FirstName、LastName和UserId)。
⑶、返回 Unicode字符
Ajax .NET包裝器能夠從服務器向客戶機返回Unicode字符。為此,數據在返回之前必須在服務器上用html編碼。比如:
|
1
2
3
4
5
6
7
8
9
|
[Ajax.AjaxMethod]
public
string
Test1(
string
name,
string
email,
string
comment)
{
string
html =
""
;
html +=
"Hello "
+ name +
"<br>"
;
html +=
"Thank you for your comment <b>"
;
html += System.Web.HttpUtility.HtmlEncode(comment);
html +=
"</b>."
;
return
html;
}
|
⑷、自定義轉換器
我們已經看到,Ajax .NET包裝器能夠處理很多不同的.NET類型。但是除了大量.NET類和內建類型以外,包裝器對不能正確返回的其他類型僅僅調用ToString()。為了避免這種情況,Ajax .NET包裝器允許開發人員創建對象轉換器,用於在服務器和客戶機之間平滑傳遞復雜對象。
5、會話訪問
|
1
2
3
4
5
6
7
|
[Ajax.AjaxMethod(Ajax.HttpSessionStateRequirement.Read)]
public
void
DocumentReleased()
{
if
(System.Web.HttpContext.Current.Session[
"DocumentsWaiting"
] ==
null
)
{
//...
}
}
|
