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ù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

呼叫中心專家ASP.NETWebForm也可以這樣用Ajax對于WebForm項目,進行Ajax操作大概有三種方式:web服務(.asmx文件)

,

一般處理程序(.ashx)和

一些Ajax控件。對于.net提供的ajax控件,暫且不說,只說另外兩種方式,都需要引入額外的代碼文件對Ajax進行操作(asmx和ashx,且web服務還要引入一個cs文件與之對應),假如要對Example.aspx這個頁面添加一些自定義的Ajax操作,并且這些Ajax操作并不會在別的頁面上用到,如此不得不引入額外的代碼文件完成這個操作,假如這個Ajax操作很簡單,只需要一個簡單的函數(shù)就可以執(zhí)行,那豈不是很麻煩的過程嗎?如此一來,隨著項目中Ajax操作的增多,ashx和asmx文件都會隨著時間的增長而增長,項目的維護也會隨之加倍。為什么我們不能把Ajax操作的后臺代碼直接放在Example.aspx對應的Example.aspx.cs文件里?如果能這樣做,以上兩種煩惱都會迎刃而解,不是嗎?于是,按照以上思路,實現(xiàn)了如下Ajax框架。先來看這個框架的實現(xiàn)機制:上圖是自己畫的一個縮減版IIS接收到一個aspx請求的HttpApplication管線和Page在執(zhí)行ProcessRequest()方法中的頁面生命周期的部分事件。Page本身是繼承自IHttpHandler接口,IHttpHandler提供了一個重要的約束方法ProcessRequest,該方法是對接收到的信息(HttpContext)進行具體的處理同樣,一般處理程序和web服務也實現(xiàn)了自己的IHttpHandler,并以此提供一些Ajax服務。具體的操作過程請自行查找MSDN。原理是在頁面生命周期開始的第一個事件PreInit進行一些處理,一旦發(fā)現(xiàn)劫持到的請求是一個ajax請求,那么利用C#的反射來調用aspx.cs中定義的方法,執(zhí)行完方法之后,調用Response.End()方法,調用這個方法會直接跳到管線的EndRequest事件,從而結束請求,這樣就無需走一些沒有必要的頁面生命周期的步驟,從而完成一個Ajax操作。如果發(fā)現(xiàn)是一個正常的操作,那么就走正常流程。下面以一個簡單例子說明該Ajax框架的使用:1.

添加一個解決方案2.

新建一個Default.aspx

頁面3.

在Default.aspx.cs頁面中創(chuàng)建一個被調用的測試方法:public

List<string>

TestAjaxMethod(int

a,

string

b,

float

c)

{

return

new

List<string>

{

a.ToString(),

b,

c.ToString()

};

}

4.

在Default.aspx中寫一個Ajax請求PowerAjax.AsyncAjax(‘TestAjaxMethod’,

[1,

2,

"333","sss"],

function

(SucceessResponse)

{

//

成功后的代碼

});

PowerAjax.js是用Jquery專門為這個框架封裝的一個及其簡單的JS類庫,這個類庫中有兩個主要的方法:PowerAjax.AsyncAjax和PowerAjax.SyncAjax,一個提供同步操作,一個提供異步操作,參數(shù)有三個:第一個參數(shù)是即將操作在aspx.cs的Ajax方法的名字(用名字反射方法)。第二個參數(shù)是一個以數(shù)組形式組成參數(shù)列表數(shù)據(jù)。第三個參數(shù)是操作成功之后執(zhí)行執(zhí)行的回調方法,與c#中的委托一個道理。以下為這個簡單JS庫的代碼:var

PowerAjax

=

function

()

{

}

PowerAjax.__Private

=

function

()

{

}

//

進行異步操作

PowerAjax.AsyncAjax

=

function

(methodName,

paramArray,

success)

{

PowerAjax.__Private.Ajax(methodName,

paramArray,

success,

true);

}

//

進行的是同步操作

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("服務器內(nèi)部錯誤:"

+

errorTitle);

}

}

});

}

5.

更改Default.aspx.cs的繼承頁面為AjaxBasePage

public

partial

class

_Default

:

AjaxBasePage

6.

主要基類:AjaxBasePage類如下代碼:public

class

AjaxBasePage

:

System.Web.UI.Page

{

///

<summary>

///

是否是一個ajax請求。

///

</summary>

public

bool

IsAjaxRequest

{

get;

private

set;

}

///

<summary>

///

如果是Ajax請求,劫持頁面生命周期的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請求,繼續(xù)執(zhí)行頁面生命周期的剩余事件

base.OnPreInit(e);

}

}

}

該類重寫了PreInit方法,判斷請求是否是一個Ajax請求。通過AjaxRequest類接收并處理接收到的請求,提取出一些有效的數(shù)據(jù),比如說是否是一個Ajax請求,方法的名字,參數(shù)列表(AjaxParameter類)。至于AjaxParameter類,內(nèi)部用的數(shù)據(jù)結構其實是一個字典,并使用索引來提供對數(shù)據(jù)的方便訪問,提供一個Count屬性,方便獲取參數(shù)的個數(shù)。

如下代碼public

class

AjaxParameter

{

private

IDictionary<int,

string>

m_DictionaryParamsData

=

new

Dictionary<int,

string>();

///

<summary>

///

返回參數(shù)的個數(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("請求方法的參數(shù)的個數(shù)限制為:0-5");

}

return

this.m_DictionaryParamsData[index];

}

}

public

AjaxParameter(IDictionary<int,

string>

paramsData)

{

this.m_DictionaryParamsData

=

paramsData;

}

}

AjaxRequest類的設計思路其實是模仿HttpContext設計,HttpContext能夠從基礎的http請求報文分析出以后處理將要用到的數(shù)據(jù)(response,request,session,cookie等等)數(shù)據(jù),而AjaxRequest通過分析Ajax的Post請求的數(shù)據(jù)域Data分析出各種以后會用到的數(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>

///

是否是一個Ajax請求。

///

</summary>

public

bool

IsAjaxRequest

{

get;

private

set;

}

///

<summary>

///

請求的方法名字。

///

</summary>

public

string

MethodName

{

get;

private

set;

}

///

<summary>

///

參數(shù)數(shù)據(jù)。

///

</summary>

public

AjaxParameter

Parameters

{

get

{

return

this.m_AjaxParameter;

}

}

#endregion

#region

構造函數(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

實例方法

public

static

AjaxRequest

GetInstance(NameValueCollection

nameValueCollection)

{

return

new

AjaxRequest(nameValueCollection);

}

#endregion

#region

ToString

public

override

string

ToString()

{

return

this.MethodName;

}

#endregion

}

通過分析AjaxRequest的屬性IsAjaxRequest可判斷是否為Ajax請求,若該請求為一個Ajax請求,那么創(chuàng)建一個AjaxApplication實例,在創(chuàng)建AjaxApplication實例的過程中會利用當前頁面和AjaxRequest提供的數(shù)據(jù)進行實際方法的調用(反射),該類是執(zhí)行Ajax方法的核心類,其中會判斷是否讀取的到的方法是一個有效的方法,并判斷從JS中AjaxApplication傳入的參數(shù)類型的有效性,目前只提供對以下13中參數(shù)提供支持,如下:(String、Boolean、Int32、Int64、UInt32、UInt64、Single、Double、Decimal、DateTime、DateTimeOffset、TimeSpan、Guid)

如果方法中出現(xiàn)非以上類型,將會拋出異常。為了方便Ajax的調試,在JS前段類庫中我會對異常進行處理,并拋出Error,Error信息有效的截取了繼承自Exception的拋出信息,至于如何獲

得更加詳細的JS調試信息,以后JS庫中可能會做提供更加詳細的調用信息,畢竟框架是在改進中進行的。如下是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個參數(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}

個(從0開始計數(shù))參數(shù)類型不匹配,應該為

{2}

類型

請檢查!",

methodInfo.Name,

i,

parameterInfo.ParameterType.Name);

throw

new

FormatException(format);

}

}

return

parameterData.ToArray();

}

else

{

throw

new

InvalidOperationException("沒有發(fā)現(xiàn)此方法,請檢查該方法簽名(方法必須為public)");

}

}

///

<summary>

///

類型轉換。支持

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等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論