ASP NET WebForm也可以這樣用Ajax11_第1頁
ASP NET WebForm也可以這樣用Ajax11_第2頁
ASP NET WebForm也可以這樣用Ajax11_第3頁
ASP NET WebForm也可以這樣用Ajax11_第4頁
ASP NET WebForm也可以這樣用Ajax11_第5頁
已閱讀5頁,還剩7頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論