ASP.NET 4 AJAX Library簡介(二)

by Vivid 5. 一月 2011 17:24

贊助廣告

 

  • 作 者:許薰尹
  • 審 稿:張智凱
  • 文章編號:N110110801
  • 出刊日期:2011/01/05

本文將延續上一篇「ASP.NET 4 AJAX Library簡介(一)」介紹ASP.NET AJAX Library,利用JavaScript與jQuery建立一個可以從用戶端透過Web服務或WCF服務將修改的資料,送回伺服端的資料庫儲存,並介紹如何在MVC的架構下來應用它們。

資料繫結

ASP.NET AJAX Library用戶端樣版提供了幾種資料繫結的方式來展示資料,包含:

l 單向資料繫結 (One-Way Live Binding)

l 雙向資料繫結 (Two-Way Live Binding)

l 一次性資料繫結 (One-Time Binding)

通常單向資料繫結或一次性資料繫結都是把資料從伺服端下載到用戶端來做展現,前述範例使用的內嵌繫結運算式(Inline binding expression)語法: {{expression}},僅能夠將資料顯示,當資料變動時,顯示的資料不會更新。和一次性資料繫結不一樣的是,單向、雙向資料繫結則可以反應出底層資料的變動,當底層資料變動時,UI會展現最新資料。

例如以下範例透過DataView用戶端控制項,利用單向資料繫結語法{binding RegionID }與{binding RegionDescription } 顯示出地區資料清單。

<head runat="server">

<title></title>

<style type="text/css">

.sys-template{ display: none;}

.selected{ background-color: red;}

</style>

<script src="../Scripts/MicrosoftAjax/Start.debug.js" type="text/javascript"></script>

<script type="text/javascript">

Sys.require([Sys.components.dataView, Sys.scripts.WebServices]);

</script>

</head>

<body xmlns:sys="javascript:Sys"

xmlns:dataview="javascript:Sys.UI.DataView">

<form id="form1" runat="server">

<table id="regionView">

<thead>

<tr>

<td>

RegionID

</td>

<td>

RegionDescription

</td>

</tr>

</thead>

<tbody class="sys-template" sys:attach="dataview"

dataview:autofetch="true"

dataview:dataprovider="../Services/MyWCFService.svc"

dataview:fetchoperation="GetRegions"

dataview:selecteditemclass="selected">

<tr sys:command="select">

<td>

{binding RegionID }

</td>

<td>

{binding RegionDescription }

</td>

</tr>

</tbody>

</table>

</form>

</body>

</html>

雙向繫結可以在底層資料變動時,更新畫面上顯示的值,例如以下範例展示在你點選其中的一筆地區資料時,將詳細資訊呈現底下詳細資料的文字方塊中顯示,當你修改文字方塊中的資料時,資料會及時修改:

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title></title>

<script src="../Scripts/MicrosoftAjax/Start.debug.js" type="text/javascript"></script>

<script type="text/javascript">

Sys.require([Sys.components.dataView, Sys.scripts.WebServices]);

</script>

<style type="text/css">

.sys-template

{

display: none;

visibility: hidden;

}

.myselected

{

color: white;

font-weight: bold;

background-color: Silver;

}

</style>

</head>

<body xmlns:sys="javascript:Sys" xmlns:dataview="javascript:Sys.UI.DataView">

<h1>地區清單</h1>

<div id="top">

<table id="regionListView">

<thead>

<tr>

<td>RegionID</td>

<td>RegionDescription</td>

</tr>

</thead>

<tbody class="sys-template"

id ="regionView"

sys:attach="dataview"

dataview:autofetch="true"

dataview:dataprovider="../Services/MyWCFService.svc"

dataview:fetchoperation="GetRegions"

dataview:selecteditemclass="myselected">

<tr sys:command="select">

<td>{binding RegionID }</td>

<td>{binding RegionDescription }</td>

</tr>

</tbody>

</table>

</div>

<br />

詳細資料

<div class="sys-template"

sys:attach="dataview"

dataview:autofetch="true"

dataview:data="{binding selectedData,source=$regionView}">

<span>RegionID:</span>

<input type="text" id="detailsRegionID" sys:value="{binding RegionID}" />

<br />

<span for="detailsRegionDescription">RegionDescription:</span>

<input type="text" id="detailsRegionDescription" sys:value="{binding RegionDescription}" />

</div>

</body>

</html>

詳細資料的<div>項目利用sys:attach指定它是一個DataView控制項的樣版,而dataview:data則使用資料繫結運算式,繫結到上方regionView選取的那一筆地區資料。執行的結果,當你更改下方文字方塊的內容時,會及時反應在上方的地區清單:

clip_image002

圖 1:雙向繫結

將修改的資料送到伺服器

ASP.NET AJAX Client Library也可以和遠端服務整合,將用戶端使用者對資料的異動寫回伺服端,例如寫回伺服端的資料庫。ASP.NET AJAX Client Library提供一個DataContext元件,它是一個代理程式,連結用戶端應用程式和伺服器,負責與遠端的服務如WCF、ASMX或WCF Data Service來溝通,也提供追蹤用戶端物件異動的能力,能記錄異動的類型(新增、刪除或修改資料),以便讓你可以透過DataContext元件將資料送到遠端的服務,將異動寫回資料庫。

在這一小節中,我希望能夠利用WCF服務讀取Norhwind資料庫Region資料表資料,利用DataView用戶端控制項顯示出地區資料清單。當你點選其中的一筆地區資料時,將詳細資訊呈現在文字方塊中顯示,您可以修改其中的地區資料,再將資料送到伺服端,以利用WCF服務的操作寫回資料庫中。延續先前的MyWCFService.svc WCF服務範例,若想要讓它可以更新資料,可以在服務程式中先加入以下定義,Change泛型類別記錄異動的資料類型與資料;ChangeOperationType列舉型別表列資料異動類型。

public class Change<T>

{

public ChangeOperationType action;

public T item;

}

public enum ChangeOperationType { insert, update, remove }

接著在服務之中加入一個SaveRegion Operaton,傳入List<Change<Region>>物件當參數:

[OperationContract]

public void SaveRegion(List<Change<Region>> changeSet) {

foreach (var c in changeSet) {

if (c.action ==ChangeOperationType.update) {

Region reg = c.item;

using (NorthwindDataContext context = new NorthwindDataContext()) {

context.Regions.Attach(reg);

context.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, reg);

context.SubmitChanges();

}

}

}

若使用者要進行資料的修改動作,就叫用NorthwindDataContext的SubmitChanges方法寫入資料庫。在網頁的部分利用DataContext物件從MyWCFService.svc服務的GetRegions方法讀取資料。若要將異動寫回伺服端,你需要設定dataContext 的saveOperation屬性為欲用來進行資料修改的服務之操作名稱:

<script type="text/javascript">

Sys.require([Sys.components.dataView, Sys.components.dataContext], function () {

var dataContext = Sys.create.dataContext({

serviceUri: "../Services/MyWCFService.svc",

saveOperation: "SaveRegion"

});

接著定義了DataView物件,並將DataView的dataProvider屬性設定為先前建立的dataContext物件:

var cate = $("#RegionView").dataView(

{

dataProvider: dataContext,

fetchOperation: "GetRegions",

autoFetch: true

});

最後希望使用者在網頁互動過程中,能夠透過dataContext來儲存異動,因此利用$addHandler註冊一個事件處理常式,在使用者點選網頁上的存檔按鈕時,呼叫dataContext的saveChanges方法將異動送到伺服端處理,並顯示「資料已儲存!」訊息:

$addHandler(Sys.get("#btnSave"), "click", function () {

dataContext.saveChanges(function () { alert("資料已儲存!"); });

});

});

</script>

網頁中繫結到DataView的div項目中包含一個子div項目,標註了「sys:command="select"」,當使用者點選了此項目,將會觸發select命令。

<body xmlns:sys="javascript:Sys"

xmlns:dv="javascript:Sys.UI.DataView" >

地區清單

<div id="RegionView" class="sys-template" >

<div sys:command="select" >

<div style="cursor:pointer;" >

<span>{binding RegionID}</span>

<span>{binding RegionDescription}</span>

</div>

</div>

</div>

<hr />

當使用者點選RegionView中任一筆Region資料,我們利用以下div項目來顯示詳細資料。利用sys:attach指明它是DataView控制項的樣版;而dv:data則是利用資料繫結運算式,指定詳細資料繫結到RegionView:

<div id="detail"

class="sys-template"

sys:attach="dv"

dv:data="{binding selectedData, source=$RegionView}">

明細資料

<br />

<input type="text" sys:value="{binding RegionID}" disabled />

<br />

<input type="text" sys:value="{binding RegionDescription}" />

</div>

<button id="btnSave">儲存</button>

</body>

執行結果參考如下:

clip_image004

圖 2:編輯資料

當網頁第一筆資料的RegionDescription值從「Eastern」修改為「Eastern 1111」時,使用Firefox的Firebug我們利用Firebug追蹤網頁的執行結果:

clip_image006

圖 3:利用Firebug追蹤網頁的執行結果。

在你叫用WCF的SaveRegion方法時,網頁會送出以下JSON資料到伺服端:

{"changeSet":[{"action":1,"item":{"__type":"Region:#","RegionDescription":"Eastern 1111 ","RegionID":1}}]}

ASMX Web Services

使用ASP.NET Client Library呼叫Web Service服務的方式基本上和呼叫WCF雷同。只要直接在網站專案加入一個Web Service檔案,例如將名稱命為「MyWebService.asmx」。然後在MyWebService類別上方套用ScriptService Attribute,以便利用AJAX來叫用服務提供的方法:

<%@ WebService Language="C#" Class="MyWebService" %>

using System;

using System.Web;

using System.Web.Services;

using System.Web.Services.Protocols;

using System.Collections.Generic;

using System.Linq;

[WebService(Namespace = "http://uuu.com/MyWebService")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

[System.Web.Script.Services.ScriptService]

public class MyWebService : System.Web.Services.WebService {

[WebMethod]

public List<Region> GetRegions() {

using (NorthwindDataContext context = new NorthwindDataContext())

{

return context.Regions.ToList();

}

}

}

MyWebService類別之中包含一個名為GetRegions的方法,上方套用了WebMethod Attribute,利用LINQ to SQL取得NorthwindDataContext中Regions所有資料。在網頁的部分,叫用Web Service與叫用WCF服務的語法差不多,只要將DataView的dataProvider設定成MyWebService.asmx,將fetchOperation設定成要呼叫的WebMethod就行了:

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<title>Retrieving Data from a Web Service (ASMX) using the DataView</title>

<script src="../Scripts/MicrosoftAjax/Start.debug.js" type="text/javascript"></script>

<script type="text/javascript">

Sys.require([Sys.components.dataView, Sys.scripts.WebServices], function () {

$("#RegionView").dataView( {

dataProvider: "../Services/MyWebService.asmx",

fetchOperation: "GetRegions",

autoFetch: true

});

});

</script>

</head>

<body>

<div id="RegionView" class="sys-template">

<ul>

<li>{{RegionDescription}}</li>

</ul>

</div>

</body>

</html>

WCF 資料服務

WCF 資料服務(WCF Data Service)先前被稱做是ADO.NET資料服務(ADO.NET Data Service),在.NET Framework 4正名為WCF資料服務。您也可以讓它當做ASP.NET AJAX的資料來源。底下的範例建立一個ADO.NET Entity Data Model當做是WCF資料服務的資料來源,名稱為Northwind.edmx。讀取Northwind資料庫中所有資料表資料,模型的命名空間為「NorthwindModel」。接著就可以在專案中加入一個WCF Data Service:

clip_image008

圖 4:加入WCF資料服務

修改MyDataService類別使其繼承自DataService< NorthwindEntities >,然後叫用DataServiceConfiguration類別開放存取權限:

namespace CallADONETWebServices {

public class MyDataService : DataService< NorthwindEntities > {

public static void InitializeService(DataServiceConfiguration config) {

config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);

config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);

config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;

}

}

}

網頁加入以下程式來叫用服務,在程式中,使用openDataContext來叫用服務,設定serviceUri屬性來指明WCF資料服務的所在位置。接著把openDataContext指定給DataView的dataProvider屬性,以便透過他來繫結並展示資料。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title></title>

<script src="Scripts/MicrosoftAjax/jQueryStart.debug.js" type="text/javascript"></script>

<script type="text/javascript">

Sys.require([Sys.components.dataView, Sys.components.openDataContext], function () {

var dataContext = Sys.create.openDataContext({

serviceUri: "WcfDataService1.svc"

});

var cate = $("#CategoryView").dataView( {

dataProvider: dataContext,

fetchOperation: "Categories",

autoFetch: true,

itemRendered: DataRendered

});

});

function DataRendered(dataView, ctx) {

Sys.binding(Sys.get("li", ctx), "innerHTML", ctx.dataItem, "CategoryName");

}

</script>

</head>

<body>

<div id="CategoryView" class="sys-template">

<div>

<li />

<span />

</div>

</div>

</body>

</html>

若要使用繫結語法針對屬性做繫結,可以參考以下範例:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<title></title>

<script src="Scripts/MicrosoftAjax/jQueryStart.debug.js" type="text/javascript"></script>

<script type="text/javascript">

Sys.require([Sys.components.dataView, Sys.components.openDataContext], function () {

var dataContext = Sys.create.openDataContext({

serviceUri: "WcfDataService1.svc"

});

var cate = $("#CategoryView").dataView( {

dataProvider: dataContext,

fetchOperation: "Categories",

autoFetch: true

});

});

function DataRendered(dataView, ctx) {

Sys.binding ($("li", ctx), "innerHTML", ctx.dataItem, "CategoryName");

}

</script>

</head>

<body>

<div>

<ul id="CategoryView" class="sys-template">

<li>{{ CategoryID}} - {{ CategoryName}}</li>

</ul>

</div>

</body>

</html>

AJAX MVC架構

在ASP.NET 4版本中推出了MVC Framework 2.0版,可以讓你透過模型-檢視-控制器(Model-View-Control)模式來設計網站程式。模型(Model)代表網站要使用的資料;檢視(View)代表應用程式用來展示的使用者界面控制器(Controller)用來處理使用者在View所進行的互動。當然ASP.NET AJAX Library也對MVC架構提供了相當多的資源。例如您可以利用Visual Studio 2010建立一個ASP.NET MVC 2 Web Application。

clip_image010

圖 5:建立一個ASP.NET MVC 2 Web Application。

這個範例的資料部分將透過LINQ to SQL來提供,取出Northwind資料庫Region資料表內容。因此您可以在專案中,Model目錄中加入一個LINQ to SQL類別,將其命名為「NW.dbml」,從伺服器總管將Region資料表拖曳到DBML設計畫面。

接著在HomeController.cs 檔案中HomeController類別內,加入以下GetRegions方法:

public JsonResult GetRegions() {

NWDataContext dc = new NWDataContext();

IEnumerable<Region> regs=dc.Regions.ToList();

return Json(regs);

}

比較特別的是,這個GetRegions方法需要利用Controller.Json方法來回傳一個JsonResult物件,因此範例中將IEnumerable<Region>轉型成JSON格式的資料後回傳。

展開Views/Home目錄下的Index.aspx,在asp:Content之中加入以下程式碼,相信這段程式碼已經見過太多次,不需再解釋了:

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

<h2><%= Html.Encode(ViewData["Message"]) %></h2>

<p>

To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.

</p>

<script src="http://ajax.microsoft.com/ajax/act/40412/jQueryStart.js" type="text/javascript"></script>

<script type="text/javascript">

Sys.require([Sys.components.dataView, Sys.scripts.WebServices], function () {

var dataView = $('#RegionTemplate).dataView( {

dataProvider: "/Home/GetRegions",

autoFetch: true

});

});

</script>

<div id="RegionTemplate" class="sys-template">

{{RegionID}} {{RegionDescription}}

<br />

</div>

</asp:Content>

當網站執行時,首頁便會呈現出Region資料表資料。

clip_image012

圖 6:MVC架構

除錯

ASP.NET Web應用程式的專案中,可以將專案設定為Release模式與debug模式。Release模式通常會針對效能做最佳化處理,而除錯模式則提供較多的除錯機制,例如型別檢查等,在ASP.NET Web應用程式的web.config檔案中將compilation項目的debug設定為true時,將會載入除錯版的Script來執行 (也就是檔名後面有加上debug字眼的檔案);若debug設定為false時,就會載入Release版的Script來執行。預設當你建立一個ASP.NET Web應用程式專案,組太檔案中會有如下設定:

<system.web>

<compilation debug="true" targetFramework="4.0">

</compilation>

</system.web>

將來在網站部署之前要注意,需將組態檔案compilation 區段debug設定為false,另外網頁若有使用到ScriptManager控制項,需將其ScriptMode設定為Release。不過,網頁的Page指示詞中debug attribute不會影響ASP.NET AJAX應用程式。ScriptManager控制項會參考Web.config檔案以及控制項的IsDebuggingEnabled、ScriptMode屬性來判斷是否使用除錯版的腳本程式。

總結

ASP.NET Ajax Library是一個JavaScript Framework,用來建立用戶端Web應用程式。您可以建立純Ajax應用程式,換句話說不一定要寫成aspx程式,在HTML的網頁之中也可以使用。ASP.NET Ajax Library完全在用戶端處理,不需用到伺服端的相關技術,增進WebForms類型網頁的執行速度。

在設計網站時,您可以使用:

l 完全用戶端解決方案:完全使用Microsoft Ajax Library,不使用伺服器控制項。

l 用戶端混合伺服端解決方案:同時使用Microsoft Ajax Library和ASP.NET伺服器控制項。

 
   

Tags:

NET 開發 | 許薰尹Vivid Hsu | .NET Magazine國際中文電子雜誌

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List