一、 導言
我們知道,ASP.net應用程式事實是在伺服器上啟動並執行,使用者的請求要不斷地送往遠端伺服器,伺服器執行完本地的程式後把重新裝載頁面再發送用戶端。所以就出現了不斷重新整理的問題,頁面不斷閃爍。使用者不厭其煩,運行效率也大大4降低,伺服器的負荷加重。事實,用戶端的請求在某一時刻只是通過向 Web 服務器提交新的請求來檢索對使用者輸入所做的響應。這種情況下,開發人員可以使用 JavaScript 在用戶端上載入所有響應,從而提供更好的使用者體驗。遺憾的是,在很多情況下,不必將所有響應都返回或載入到 JavaScript 要更好,只返回所要的結果,執行過程仍然在伺服器上運行。AJAX 提供了一種新的中間選擇,能夠在維持及時響應和靈活性的同時利用基於伺服器的應用程式。
AJAX依靠伺服器作為中介來分發和處理請求。為了完成這項工作,.net封裝類依賴於用戶端的請求對象,而xmlHttpRequest對象被大部分的瀏覽器支援,因此使用這個對象是一個不錯的解決方案。
因此,為了實現不重新整理的頁面,我們的用戶端頁面做成靜態頁面。靜態頁面通過Ajax.net調用.net類的方法。這是一種最簡潔又高效的解決方案。
二、 如何應用Ajax.net
1.在工程中引入Ajax.dll檔案。
Ajax.dll是微軟開發的應用在asp.net上的一個類庫檔案。該類庫封裝了XmlHttpRequest請求伺服器的實現細節,是Ajax知識應用在asp.net平台上的解決技術。在.net項目中,添加上對其的引用,然後就可以開始使用ajax.dll封裝進行開發了。
2.在web.config中設定HttpHandle
為了使其可以工作,第一步必須做的是在web.config中安裝設定封裝包的HttpHandle,不去詳細解釋HttpHandle是如何工作的,我們只需要瞭解他們可以用來處理asp.net請求。例如,所有的目的為*.aspx的請求可以通過 System.Web.UI.PageHandlerFactory類發送到控制控制代碼,簡單的說,我們把任何向ajax/*.ashx的請求發送到 Ajax.PageHandlerFactory的請求處理控制代碼。
3.編寫服務端函數
現在我們編寫伺服器端函數,他們可以被用戶端非同步調用。儘管現在還不能支援全部的傳回型別,我們仍堅持伺服器端添加功能。在codebehind檔案的頁面類裡,添加下面的方法:
[Ajax.AjaxMethod()] public int ServerSideAdd(int firstNumber, int secondNumber) { return firstNumber + secondNumber; } |
注意,這個函數有Ajax.AjaxMethod()定製屬性,屬性服務會告知ajax封裝類為此方法建立一個javascript代理,這樣才能被用戶端調用。
三、 應用執行個體(點擊下載源碼)
我們的應用程式主要是對資料庫的操作,資料庫的資料通過頁面的表格呈現,頁面完成增加、刪除、更新、查詢等功能。更主要的是它是一個通用的並且實現方法極為巧妙的例子。任何頁面沒有重新整理現象並且代碼十分精巧。下面的就通過Ajax技術實現這些功能。
·建立工程HttpForAjax,並在您的工程中引入Ajax.dll檔案。
·在您的Web.config中加上。
<httpHandlers> <add verb="POST,GET" path="ajax/*.ashx" type="Ajax.PageHandlerFactory, Ajax"/> </httpHandlers> |
·建立您的HTML頁。
1. 向工程裡添加HTML頁InfoClass.htm。該頁面完成查詢、常用工具及資料展現等功能。
頁面主要放了四個DIV,一個是樹" divTree "。一個是查詢區叫"divFindTable"的,一個是工具列叫
"divToolbar"的,一個是資料區叫"divDataGrid"的。如:
2. 在 <HEAD>與</HEAD>間加入一些引用如下:
<script src=js/Xml.js></script> <link href="css/myStyle.css" type="text/css" rel="stylesheet"> <script src="/HttpForAjax/ajax/common.ashx" type="text/javascript"></script> <script src="/HttpForAjax/ajax/Ttyu.AjaxData,HttpForAjax.ashx" type="text/javascript"></script> |
說明:Xml.js是用javascript寫的一些用戶端程式。
myStyle.css為樣式風格檔案。
common.ashx為調用Ajax的公用方法。
HttpForAjax.ashx為下面我們要用Ajax編寫的類的引用。其中HttpForAjax為工程的命名空間。
Ttyu.AjaxData為自己開發的類,其中Ttyu為命名空間,AjaxData為類名。
3. 用javascript編寫指令碼方法,
function Init() { DomTree=new dhtmlXTreeObject(document.getElementById('divTree'),"100%","100%",0); DomTree.setImagePath("imgs/"); DomTree.enableDragAndDrop(true) DomTree.setDragHandler(myDragHandler); DomTree.setOnClickHandler(SelectTreeNode); var s= AjaxData.GetXmlTree().value; DomTree.loadXMLString(s); DomTree.openItem("R_1"); SelectTreeNode("R_1"); divToolbar.innerHTML=AjaxData.GetToolBarTable(TableName).value; divDataGrid.innerHTML=GetTableOuterHTML(TableName); } |
Init方法通過Ajax的GetXmlTree方法得到樹的內容,GetToolBarTable取得工具列的內容。通過GetTableOuterHTML方法取得物理表tInfoClass的所有資料並通過表格展現出來。
function Find() { var Table=AjaxData.GetXmlFindTable("年級名稱 like '%"+txtName.value +"%'"); divDataGrid.innerHTML=Table.value; } |
查詢方法Find()是通過Ajax的GetXmlFindTable方法按年級名稱查詢並把結果展現出來。
function OpenAddWeb() { var RetID =OpenAddWin('InfoClass_edit.aspx?IsAdd=true',370,300); if(RetID==-1) return; InsertRow(DataGrid1,RetID); } |
OpenAddWeb方法開啟InfoClass_edit.aspx頁在該頁上完成增加資料的功能。如果傳回值不為-1則表示有新資料增加的並把資料插入到表格的最後一行。RetID表示最後一行的ID.
function OpenEditWeb(ThisCell) { var ID=ThisCell.previousSibling.previousSibling.innerText; var RetID =OpenAddWin("InfoClass_edit.aspx?ID="+ID+"&IsAdd=false",370,300); if(RetID==-1) return; //有更新行 var CurrRow=ThisCell.parentElement SetRowText(CurrRow); // SetRowText(CurrRow,RetDataRow); } |
OpenEditWeb方法是當使用者點擊的儲存格後開啟InfoClass_edit.aspx頁在該頁上完成編輯該行資料的功能。如有更新行則把當前行的內容更換..
·建立Ajax類。(見檔案AjaxData.cs)命名空間為Ttyu,類名為AjaxData。
1. 定義靜態變數mDt。mDt是讀取到物理表的資料並儲存在記憶體中的資料表對象。我們的主要操作都是靠它完成。定義為靜態是我們不希望反覆訪問資料庫。我們一次性讀取,永久使用。
static public DataTable mDt; |
2.定義我們的主要方法。在每個方法的上行加上[Ajax.AjaxMethod()]。
//得到表TableName的所得資料,以XML字串返回 [Ajax.AjaxMethod()] public string GetTableOuterHTML(string TableName) { DataTable dt=db.DB.GetDataTable(TableName); mDt=dt; return db.GetTableOuterHTML(dt.DefaultView); } |
GetTableOuterHTML方法是由物理表名讀取到記憶體中並通過其視圖得到以XML格式的Table。這裡我們讀取後儲存在mDt中。用資料表的視圖是我們的查詢也通過該方法呈現資料。
//得到表TableName的所得資料,以XML字串返回 [Ajax.AjaxMethod()] public string GetXmlFindTable(string RowFilter) { DataTable Dt=mDt; DataView dv=Dt.DefaultView; dv.RowFilter=RowFilter; return db.GetTableOuterHTML(dv); } |
GetXmlFindTable是按查詢條件從mDt中查詢到資料並返回給用戶端。
//刪除行 [Ajax.AjaxMethod()] public bool DeleteRow(string TableName,int ID) { string SQL = "delete from " + TableName + " where ID=" + ID; bool isSuccess= db.DB.ExecuteSQL(SQL); if(isSuccess) { DataRow dr=mDt.Select("ID="+ID)[0]; mDt.Rows.Remove(dr); } return isSuccess; } |
DeleteRow是刪除物理表的一行,並在mDt中也同步地刪除。
//把資料行轉化為數組返回 [Ajax.AjaxMethod()] public object GetDataRow(int iID) { DataRow dr=mDt.Select("ID="+iID)[0]; return dr.ItemArray;//數字類型不可為空 } GetDataRow是從記憶體表mDt得到ID號為iID的一行,通過數組方式返回給用戶端。 [Ajax.AjaxMethod()] public string GetToolBarTable(string TableName) { return db.GetToolBarTable(TableName); } |
GetToolBarTable是組織成工具列的內容返回給用戶端。
·建立業務資料類ttyuPKData。(見檔案ttyuPKData.cs)命名空間為Ttyu,類名為ttyuPKData。
該類中有些常用的方法。
public bool InsertDataRow(DataRow dr,int BeginColumnIndex)為向物理表中把資料行dr插入,BeginColumnIndex表示從開始的列插入。
public bool UpdateDataRow(DataRow dr,int BeginColumnIndex,string Filter) 為向物理表中把資料行dr的資料更新,BeginColumnIndex表示開始更新的列。Filter表示所要更新的行。是一篩選條件。
public string GetTableOuterHTML(DataView dv)是個通用的把資料檢視展現為Table的方法。並通過class定義樣式。
//由一個資料檢視得到該表的表頭及所有資料,以XML格式的表字串返回 public string GetTableOuterHTML(DataView dv) { StringBuilder ret = new StringBuilder(); ret.Append("<table class='DataGrid' id='DataGrid1' cellspacing=1 cellpadding=4>" ); ret.Append("<tr class='DataGridHeaderStyle'>"); ret.Append("<td width='5'> <input type='checkbox' onclick='SelectAll(this)'></td> "); //標題 foreach(System.Data.DataColumn dc in dv.Table.Columns ) { if(dc.Ordinal==0) //該列隱藏 ret.Append("<td class='IDColumn'>"+dc.ColumnName+"</td>"); else ret.Append("<td>"+dc.ColumnName+"</td>"); } ret.Append("</tr>"); //這時是視圖中篩選後的資料 foreach(DataRowView drv in dv) { DataRow dr=drv.Row;//dv.Table.Rows[i]; ret.Append(GetRowOuterHTML(dr)); } ret.Append("</table>"); return ret.ToString (); } |
·建立頁面資料編輯類(見檔案PageEdit.cs)命名空間為Ttyu.Web,類名為PageEdit。
該類是個通用的通過繼承的技巧實現了所有編輯頁(包括增加、修改資料)功能的統一處理。頁中不需要一行代碼。
結論
Ajax技術可以給用戶端提供豐富的客戶體驗,而ajax.net為您容易的實現這樣強大的功能提供了可能。靜態頁面是不出現重新整理問題的。我們的靜態頁面通過Ajax完全可與asp.net結合起來。通過.net進行背景管理。前台通過javascript調用。這樣完美的結合是解決問題的最佳方法。