版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
呼叫中心專家ASP.NETWebForm也可以這樣用Ajax對(duì)于WebForm項(xiàng)目,進(jìn)行Ajax操作大概有三種方式:web服務(wù)(.asmx文件)
,
一般處理程序(.ashx)和
一些Ajax控件。對(duì)于.net提供的ajax控件,暫且不說,只說另外兩種方式,都需要引入額外的代碼文件對(duì)Ajax進(jìn)行操作(asmx和ashx,且web服務(wù)還要引入一個(gè)cs文件與之對(duì)應(yīng)),假如要對(duì)Example.aspx這個(gè)頁面添加一些自定義的Ajax操作,并且這些Ajax操作并不會(huì)在別的頁面上用到,如此不得不引入額外的代碼文件完成這個(gè)操作,假如這個(gè)Ajax操作很簡(jiǎn)單,只需要一個(gè)簡(jiǎn)單的函數(shù)就可以執(zhí)行,那豈不是很麻煩的過程嗎?如此一來,隨著項(xiàng)目中Ajax操作的增多,ashx和asmx文件都會(huì)隨著時(shí)間的增長(zhǎng)而增長(zhǎng),項(xiàng)目的維護(hù)也會(huì)隨之加倍。為什么我們不能把Ajax操作的后臺(tái)代碼直接放在Example.aspx對(duì)應(yīng)的Example.aspx.cs文件里?如果能這樣做,以上兩種煩惱都會(huì)迎刃而解,不是嗎?于是,按照以上思路,實(shí)現(xiàn)了如下Ajax框架。先來看這個(gè)框架的實(shí)現(xiàn)機(jī)制:上圖是自己畫的一個(gè)縮減版IIS接收到一個(gè)aspx請(qǐng)求的HttpApplication管線和Page在執(zhí)行ProcessRequest()方法中的頁面生命周期的部分事件。Page本身是繼承自IHttpHandler接口,IHttpHandler提供了一個(gè)重要的約束方法ProcessRequest,該方法是對(duì)接收到的信息(HttpContext)進(jìn)行具體的處理同樣,一般處理程序和web服務(wù)也實(shí)現(xiàn)了自己的IHttpHandler,并以此提供一些Ajax服務(wù)。具體的操作過程請(qǐng)自行查找MSDN。原理是在頁面生命周期開始的第一個(gè)事件PreInit進(jìn)行一些處理,一旦發(fā)現(xiàn)劫持到的請(qǐng)求是一個(gè)ajax請(qǐng)求,那么利用C#的反射來調(diào)用aspx.cs中定義的方法,執(zhí)行完方法之后,調(diào)用Response.End()方法,調(diào)用這個(gè)方法會(huì)直接跳到管線的EndRequest事件,從而結(jié)束請(qǐng)求,這樣就無需走一些沒有必要的頁面生命周期的步驟,從而完成一個(gè)Ajax操作。如果發(fā)現(xiàn)是一個(gè)正常的操作,那么就走正常流程。下面以一個(gè)簡(jiǎn)單例子說明該Ajax框架的使用:1.
添加一個(gè)解決方案2.
新建一個(gè)Default.aspx
頁面3.
在Default.aspx.cs頁面中創(chuàng)建一個(gè)被調(diào)用的測(cè)試方法:public
List<string>
TestAjaxMethod(int
a,
string
b,
float
c)
{
return
new
List<string>
{
a.ToString(),
b,
c.ToString()
};
}
4.
在Default.aspx中寫一個(gè)Ajax請(qǐng)求PowerAjax.AsyncAjax(‘TestAjaxMethod’,
[1,
2,
"333","sss"],
function
(SucceessResponse)
{
//
成功后的代碼
});
PowerAjax.js是用Jquery專門為這個(gè)框架封裝的一個(gè)及其簡(jiǎn)單的JS類庫(kù),這個(gè)類庫(kù)中有兩個(gè)主要的方法:PowerAjax.AsyncAjax和PowerAjax.SyncAjax,一個(gè)提供同步操作,一個(gè)提供異步操作,參數(shù)有三個(gè):第一個(gè)參數(shù)是即將操作在aspx.cs的Ajax方法的名字(用名字反射方法)。第二個(gè)參數(shù)是一個(gè)以數(shù)組形式組成參數(shù)列表數(shù)據(jù)。第三個(gè)參數(shù)是操作成功之后執(zhí)行執(zhí)行的回調(diào)方法,與c#中的委托一個(gè)道理。以下為這個(gè)簡(jiǎn)單JS庫(kù)的代碼:var
PowerAjax
=
function
()
{
}
PowerAjax.__Private
=
function
()
{
}
//
進(jìn)行異步操作
PowerAjax.AsyncAjax
=
function
(methodName,
paramArray,
success)
{
PowerAjax.__Private.Ajax(methodName,
paramArray,
success,
true);
}
//
進(jìn)行的是同步操作
PowerAjax.SyncAjax
=
function
(methodName,
paramArray,
success)
{
PowerAjax.__Private.Ajax(methodName,
paramArray,
success,
false);
}
PowerAjax.__Private.Ajax
=
function
(methodName,
paramArray,
success,
isAsync)
{
var
data
=
{};
switch
(paramArray.length)
{
case
0:
data
=
{
'isAjaxRequest':
true,
'MethodName':
methodName
};
break;
case
1:
data
=
{
'isAjaxRequest':
true,
'MethodName':
methodName,
"param0":
paramArray[0]
};
break;
case
2:
data
=
{
'isAjaxRequest':
true,
'MethodName':
methodName,
"param0":
paramArray[0],
"param1":
paramArray[1]
};
break;
case
3:
data
=
{
'isAjaxRequest':
true,
'MethodName':
methodName,
"param0":
paramArray[0],
"param1":
paramArray[1],
"param2":
paramArray[2]
};
break;
case
4:
data
=
{
'isAjaxRequest':
true,
'MethodName':
methodName,
"param0":
paramArray[0],
"param1":
paramArray[1],
"param2":
paramArray[2],
"param3":
paramArray[3]
};
break;
case
5:
data
=
{
'isAjaxRequest':
true,
'MethodName':
methodName,
"param0":
paramArray[0],
"param1":
paramArray[1],
"param2":
paramArray[2],
"param3":
paramArray[3],
"param4":
paramArray[4]
};
break;
}
var
url
=
document.location.href;
$.ajax({
type:
"post",
url:
url,
data:
data,
async:
isAsync,
datatype:
"json",
contentType:
"application/x-www-form-urlencoded;
charset=UTF-8",
success:
function
(response)
{
success(response);
},
error:
function
(response)
{
if
(response.status
==
500)
{
var
errorMessage
=
response.responseText;
var
errorTitle
=
errorMessage.substring(errorMessage.indexOf("<title>")
+
7,
errorMessage.indexOf("</title>"))
throw
new
Error("服務(wù)器內(nèi)部錯(cuò)誤:"
+
errorTitle);
}
}
});
}
5.
更改Default.aspx.cs的繼承頁面為AjaxBasePage
public
partial
class
_Default
:
AjaxBasePage
6.
主要基類:AjaxBasePage類如下代碼:public
class
AjaxBasePage
:
System.Web.UI.Page
{
///
<summary>
///
是否是一個(gè)ajax請(qǐng)求。
///
</summary>
public
bool
IsAjaxRequest
{
get;
private
set;
}
///
<summary>
///
如果是Ajax請(qǐng)求,劫持頁面生命周期的PreInit的事件,直接返回Response
///
</summary>
protected
override
void
OnPreInit(EventArgs
e)
{
AjaxRequest
ajaxRequest
=
AjaxRequest.GetInstance(Request.Form);
this.IsAjaxRequest
=
ajaxRequest.IsAjaxRequest;
if
(this.IsAjaxRequest)
{
AjaxApplication
ajaxApplication
=
new
AjaxApplication(this,
ajaxRequest);
ajaxApplication.EndRequest();
}
else
{
//
如果不是Ajax請(qǐng)求,繼續(xù)執(zhí)行頁面生命周期的剩余事件
base.OnPreInit(e);
}
}
}
該類重寫了PreInit方法,判斷請(qǐng)求是否是一個(gè)Ajax請(qǐng)求。通過AjaxRequest類接收并處理接收到的請(qǐng)求,提取出一些有效的數(shù)據(jù),比如說是否是一個(gè)Ajax請(qǐng)求,方法的名字,參數(shù)列表(AjaxParameter類)。至于AjaxParameter類,內(nèi)部用的數(shù)據(jù)結(jié)構(gòu)其實(shí)是一個(gè)字典,并使用索引來提供對(duì)數(shù)據(jù)的方便訪問,提供一個(gè)Count屬性,方便獲取參數(shù)的個(gè)數(shù)。
如下代碼public
class
AjaxParameter
{
private
IDictionary<int,
string>
m_DictionaryParamsData
=
new
Dictionary<int,
string>();
///
<summary>
///
返回參數(shù)的個(gè)數(shù)。
///
</summary>
public
int
Count
{
get
{
return
this.m_DictionaryParamsData.Count;
}
}
///
<summary>
///
索引具體參數(shù)的值。
///
</summary>
///
<param
name="index"></param>
///
<returns></returns>
public
string
this[int
index]
{
get
{
if
(index
>=
5
||
index
<
0)
{
throw
new
NotSupportedException("請(qǐng)求方法的參數(shù)的個(gè)數(shù)限制為:0-5");
}
return
this.m_DictionaryParamsData[index];
}
}
public
AjaxParameter(IDictionary<int,
string>
paramsData)
{
this.m_DictionaryParamsData
=
paramsData;
}
}
AjaxRequest類的設(shè)計(jì)思路其實(shí)是模仿HttpContext設(shè)計(jì),HttpContext能夠從基礎(chǔ)的http請(qǐng)求報(bào)文分析出以后處理將要用到的數(shù)據(jù)(response,request,session,cookie等等)數(shù)據(jù),而AjaxRequest通過分析Ajax的Post請(qǐng)求的數(shù)據(jù)域Data分析出各種以后會(huì)用到的數(shù)據(jù)。如下是該類的代碼:public
class
AjaxRequest
{
private
Dictionary<int,
string>
m_DictionaryParamsData
=
new
Dictionary<int,
string>();
private
AjaxParameter
m_AjaxParameter;
private
int
m_Count
=
0;
#region
屬性
///
<summary>
///
是否是一個(gè)Ajax請(qǐng)求。
///
</summary>
public
bool
IsAjaxRequest
{
get;
private
set;
}
///
<summary>
///
請(qǐng)求的方法名字。
///
</summary>
public
string
MethodName
{
get;
private
set;
}
///
<summary>
///
參數(shù)數(shù)據(jù)。
///
</summary>
public
AjaxParameter
Parameters
{
get
{
return
this.m_AjaxParameter;
}
}
#endregion
#region
構(gòu)造函數(shù)
private
AjaxRequest(NameValueCollection
nameValueCollection)
{
this.IsAjaxRequest
=
nameValueCollection["isAjaxRequest"]
==
"true";
if
(this.IsAjaxRequest)
{
this.MethodName
=
nameValueCollection["MethodName"];
foreach
(string
value
in
nameValueCollection)
{
string
formKey
=
string.Format("param{0}",
this.m_Count);
if
(nameValueCollection[formKey]
!=
null)
{
this.m_DictionaryParamsData.Add(this.m_Count,
nameValueCollection[formKey]);
this.m_Count++;
}
}
m_AjaxParameter
=
new
AjaxParameter(this.m_DictionaryParamsData);
}
}
#endregion
#region
實(shí)例方法
public
static
AjaxRequest
GetInstance(NameValueCollection
nameValueCollection)
{
return
new
AjaxRequest(nameValueCollection);
}
#endregion
#region
ToString
public
override
string
ToString()
{
return
this.MethodName;
}
#endregion
}
通過分析AjaxRequest的屬性IsAjaxRequest可判斷是否為Ajax請(qǐng)求,若該請(qǐng)求為一個(gè)Ajax請(qǐng)求,那么創(chuàng)建一個(gè)AjaxApplication實(shí)例,在創(chuàng)建AjaxApplication實(shí)例的過程中會(huì)利用當(dāng)前頁面和AjaxRequest提供的數(shù)據(jù)進(jìn)行實(shí)際方法的調(diào)用(反射),該類是執(zhí)行Ajax方法的核心類,其中會(huì)判斷是否讀取的到的方法是一個(gè)有效的方法,并判斷從JS中AjaxApplication傳入的參數(shù)類型的有效性,目前只提供對(duì)以下13中參數(shù)提供支持,如下:(String、Boolean、Int32、Int64、UInt32、UInt64、Single、Double、Decimal、DateTime、DateTimeOffset、TimeSpan、Guid)
如果方法中出現(xiàn)非以上類型,將會(huì)拋出異常。為了方便Ajax的調(diào)試,在JS前段類庫(kù)中我會(huì)對(duì)異常進(jìn)行處理,并拋出Error,Error信息有效的截取了繼承自Exception的拋出信息,至于如何獲
得更加詳細(xì)的JS調(diào)試信息,以后JS庫(kù)中可能會(huì)做提供更加詳細(xì)的調(diào)用信息,畢竟框架是在改進(jìn)中進(jìn)行的。如下是AjaxApplication類的具體代碼:public
class
AjaxApplication
{
private
AjaxBasePage
m_AjaxBasePage;
private
object
m_ResponseData;
public
AjaxApplication(AjaxBasePage
ajaxBasePage,
AjaxRequest
ajaxRequest)
{
this.m_AjaxBasePage
=
ajaxBasePage;
Type
ajaxBasePageType
=
ajaxBasePage.GetType();
MethodInfo
methodInfo
=
ajaxBasePageType.GetMethods(BindingFlags.Public
|
BindingFlags.NonPublic
|
BindingFlags.Static
|
BindingFlags.Instance)
.FirstOrDefault(item
=>
item.Name
==
ajaxRequest.MethodName);
object[]
parameterData
=
this.GetParameterData(ajaxRequest,
methodInfo);
if
(methodInfo.IsStatic)
{
this.m_ResponseData
=
methodInfo.Invoke(null,
parameterData);
}
else
{
this.m_ResponseData
=
methodInfo.Invoke(ajaxBasePage,
parameterData);
}
}
///
<summary>
///
獲取參數(shù)數(shù)據(jù)。
///
</summary>
private
object[]
GetParameterData(AjaxRequest
ajaxRequest,
MethodInfo
methodInfo)
{
if
(methodInfo
!=
null)
{
ParameterInfo[]
parameterInfos
=
methodInfo.GetParameters();
if
(parameterInfos.Length
>
5)
{
throw
new
NotSupportedException("最多支持5個(gè)參數(shù)");
}
if
(parameterInfos.Length
>
ajaxRequest.Parameters.Count)
{
throw
new
ArgumentException("缺少參數(shù)!");
}
List<object>
parameterData
=
new
List<object>(parameterInfos.Length);
for
(int
i
=
0;
i
<
parameterInfos.Length;
i++)
{
ParameterInfo
parameterInfo
=
parameterInfos[i];
string
paramValue
=
ajaxRequest.Parameters[i];
try
{
parameterData.Add(ParseAjaxParameter(paramValue,
parameterInfo));
}
catch
(FormatException)
{
string
format
=
string.Format("傳入靜態(tài)方法
{0}
的第
{1}
個(gè)(從0開始計(jì)數(shù))參數(shù)類型不匹配,應(yīng)該為
{2}
類型
請(qǐng)檢查!",
methodInfo.Name,
i,
parameterInfo.ParameterType.Name);
throw
new
FormatException(format);
}
}
return
parameterData.ToArray();
}
else
{
throw
new
InvalidOperationException("沒有發(fā)現(xiàn)此方法,請(qǐng)檢查該方法簽名(方法必須為public)");
}
}
///
<summary>
///
類型轉(zhuǎn)換。支持
String、Boolean、Int32、Int64、UInt32、UInt64、Single、Double、Decimal、DateTime、DateTimeOffset、TimeSpan、Guid
///
</summary>
private
object
ParseAjaxParameter(string
ajaxParameterValue,
ParameterInfo
parameterInfo)
{
object
obj;
if
(parameterInfo.ParameterType
==
typeof(String))
{
obj
=
ajaxParameterValue;
}
else
if
(parameterInfo.ParameterType
==
typeof(Boolean))
{
obj
=
bool.Parse(ajaxParameterValue);
}
else
if
(parameterInfo.ParameterType
==
typeof(Int32))
{
obj
=
Int32.Parse(ajaxParameterValue);
}
else
if
(parameterInfo.ParameterType
==
typeof(UInt32))
{
obj
=
UInt32.Parse(ajaxParameterValue);
}
else
if
(parameterInfo.ParameterType
==
typeof(UInt64))
{
obj
=
UInt64.Parse(ajaxParameterValue);
}
else
if
(parameterInfo.ParameterType
==
typeof(Single))
{
obj
=
Single.Parse(ajaxParameterValue);
}
else
if
(parameterInfo.ParameterType
==
typeof(Double))
{
obj
=
Double.Parse(ajaxParameterValue);
}
else
if
(parameterInfo.ParameterType
==
typeof(Decimal))
{
obj
=
Decimal.Parse(ajaxParameterValue);
}
else
if
(parameterInfo.ParameterType
==
typeof(DateTime))
{
obj
=
DateTime.Parse(ajaxParameterValue);
}
else
if
(parameterInfo.ParameterType
==
typeof(DateTimeOffset))
{
obj
=
DateTimeOffset.Parse(ajaxParameterValue);
}
else
if
(parameterInfo.ParameterType
==
typeof(TimeSpan))
{
obj
=
TimeSpan.Parse(ajaxParameterValue);
}
else
if
(parameterInfo.ParameterType
==
typeof(Guid))
{
obj
=
Guid.Parse(ajaxParameterValue);
}
else
{
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年專業(yè)高級(jí)顧問聘任協(xié)議范例版B版
- 2025年江西貨運(yùn)從業(yè)資格試題答案大全
- 建筑工程鋁扣板施工合同
- 智能城市交通網(wǎng)絡(luò)部署合同
- 會(huì)計(jì)師事務(wù)所公關(guān)部聘用合同
- 2025年正規(guī)商品代銷合同書范文
- 港口物流船運(yùn)租賃合同
- 食品公司品控員招聘合同模板
- 河北省張家口市2024屆高三上學(xué)期期末考試數(shù)學(xué)試題(解析版)
- 圖書館建設(shè)拆遷施工合同
- 數(shù)據(jù)可視化技術(shù)智慧樹知到期末考試答案2024年
- MOOC 警察禮儀-江蘇警官學(xué)院 中國(guó)大學(xué)慕課答案
- 三基考試題庫(kù)與答案
- 2024年廣東省2024屆高三二模英語試卷(含標(biāo)準(zhǔn)答案)
- 全飛秒激光近視手術(shù)
- 2024年制鞋工專業(yè)知識(shí)考試(重點(diǎn))題庫(kù)(含答案)
- 2023-2024學(xué)年廣州大附屬中學(xué)中考一模物理試題含解析
- 綠化養(yǎng)護(hù)工作日記錄表
- 2024美的在線測(cè)評(píng)題庫(kù)答案
- 2024版高考數(shù)學(xué)二輪復(fù)習(xí):解析幾何問題的方法技巧
- 輿情監(jiān)測(cè)服務(wù)方案
評(píng)論
0/150
提交評(píng)論