top
Loading...
ASP.NET+Atlas創建客戶端Web應用程序
提要 本文介紹了Atlas框架,并探討它的客戶端和服務器端類庫及其編程模型。另外,本文還詳細剖析了一個支持Atlas功能的示例Web應用程序。

一、 開發環境說明

本文中所提供的信息適用于下列技術:Asp.net 2.0,Asp.net Atlas CTP,Visual Studio Professional 2005和Visual Web Developer 2005。

二、 簡介

Atlas是一個框架的代號,該框架對于客戶端Web應用程序的開發方面擴展了asp.net。該框架在提供一組客戶端和服務器端類來創建跨瀏覽器兼容的AJAX風格的應用程序的同時,還引入了其它特征,例如橋接技術,gadget,一個JavaScript的聲明性腳本模型和擴展。

本文將介紹Atlas框架并探討它的客戶端和服務器端類庫及其編程模型。另外,本文還詳細剖析了一個支持Atlas功能的示例Web應用程序。

三、 基于客戶端和服務器端的Web應用程序

現在,Web應用程序開發主要針對于http客戶端(瀏覽器)和服務器開發。Asp.net Web應用程序是基于服務器的(在該主機上運行),因此,對于由在客戶端上的一個服務器控件激發的每一個事件都要求一個完整的回寄。這樣的情形可以用圖1所示來描述。


圖1.一個針對asp.net Web應用程序的http回饋

只在服務器端運行Web應用程序,而幾乎不需要(或很少需要)客戶端處理,并且不會造成性能下降。不過,其缺點也很容易在一個asp.net Web應用程序發現:一個閃爍的、暫停的、不具有響應性的和相對可憐的UI;或者是,由于數據回寄和服務器過載而導致一個繁忙的線路。

要在asp.net應用程序解決這些性能障礙意味著,必須把一些加載處理移到客戶端并且利用客戶端平臺所提供的技術。客戶端平臺是可以通過腳本進行編程的,而JavaScript就是適合于這種任務的一種標準的面向對象的編程語言。

那么,上面這些客戶端平臺技術指的是什么呢?這些客戶端平臺(瀏覽器)提供了下列技術:

· 文檔對象模型:一種標準化的語言獨立的一組對象集合,允許開發者動態地控制HTML文檔的結構、內容和風格。

· 動態的超文本標記語言對象模型:一個瀏覽器供應商特定的特征集合,可以用作DOM的一個擴展。數據綁定、UI效果(例如過濾器和過渡)、HTML元素行為和事件都是在這個對象模型內部所提供的一些特征。

· XmlHttpRequest對象:它允許通過Http檢索和提交XML數據而不要求一種整個Web文檔的完整的回饋或重新生成。

· 一個JavaScript解釋器:包含在所有的Web瀏覽器中,由它處理用JavaScript書寫的命令。JScript是微軟版本的JavaScript,它最初由Netscape所創建。兩種版本都遵循ECMAScript標準—供應商中立的,跨平臺的,通用目的的腳本語言。

這些技術合在一起被稱為AJAX,代表的意思是異步JavaScript+XML;而Atlas正是一種利用這些技術的創建Web應用程序的框架。下面的圖2展示了一個支持Atlas技術的asp.net Web應用程序。

點擊放大此圖片
圖2.Http請求和響應一個支持Atlas技術的,基于客戶端的asp.net Web應用程序

四、 Atlas框架概要

該框架包含了Microsoft.Web.Atlas.dll裝配集,它包含了服務器端托管的和客戶端JavaScript API。
下圖3展示了Visual Studio的對象瀏覽器窗口中的Atlas命名空間。

點擊放大此圖片
圖3.在Microsoft.Web.Atlas.dll裝配集中的命名空間

(一) 服務器端庫

在圖3框架中展示的命名空間中提供的各種類擔任服務器端庫。該庫提供與客戶端JavaScript API一起工作的配置、Web服務和控件類。

該Web服務類把asp.net特征,例如認證、輪廓、文化和全球化等信息,暴露給客戶端JavaScript代碼以便進行異步存取。另一方面,Atlas服務器控件類,在生成這些控件時能夠“發出”JavaScript,從而使開發者免于編寫復雜的客戶端腳本。

服務器端庫還提供Atlas extender控件,它能夠提供給asp.net控件其它客戶端功能。

下列控件是服務器端庫的一部分:

· ScriptManager控件:提供了在一個Web頁面上的所有的Atlas特征,例如部分頁面更新,定制和庫客戶端腳本參考和生成,針對客戶端異步存取的Web服務引用,而異常處理是由該控件管理的。每一個需要實現Atlas功能的asp.net Web頁面或用戶控件都需要聲明這個控件的單個實例。為了在一個頁面上使用ScriptManager控件,你可以使用下列聲明性語法:

<atlas:ScriptManager
ID="ScriptManager instance identifier"
<!--enables or disables partial page rendering using UpdatePanel controls-->
EnablePartialRendering="boolean true or false"

<!--If set to false the AtlasRuntime.js file, which provides basic 'Atlas functionality is referenced by default.
If set to true the Atlas.js file, which provides the entire Atlas feature set is referenced by default.
The default value is true-->
EnableScriptComponents="boolean true or false"

OnPageError="invoked event handler on PageError "
runat="server" >

<Scripts>
<atlas:ScriptReference
<!--to reference custom script files-->
Path="path to .js file"
<!--to reference client library files that are not included automatically-->
ScriptName="name of script file e.g. AtlasUIGlitz"/>
</Scripts>
<Services>
<atlas:ServiceReference
<!--If set to true the control generates a JavaScript proxy object for asynchronous access for the referenced Web Service.
If set to false it doesn't.-->
GenerateProxy="boolean true or false"

Path="path to a Web service (e.g. asmx) file"
Type="Web service class name"
/>
</Services>
<ErrorTemplate>
<!--Markup for rendering unhandled exception messages for asynchronous postback.
Partial rendering should be enabled. The template has to define an input button with an attributes ID of value "okButton" and runat of value "server" to close the message. -->
</ErrorTemplate>
</atlas:ScriptManager>

· ScriptManagerProxy控件:對于內容頁面和用戶控件來說,如果它們的父頁面已經擁有一個定義好的ScriptManager控件,那么這個控件可以用于參考其它腳本和服務。但是,該控件不能被ScriptManager控件用于刪除腳本和服務參考。

· UpdatePanel控件:當通過ScriptManager控件支持一個Web頁面的部分生成時,UpdatePanel控件可以用于指定頁面上的區域—能夠被獨立地使用異步回饋進行更新。下列聲明性語法用于在一個Web頁面中定義一個UpdatePanel控件:

<atlas:UpdatePanel
ID="UpdatePanel instance identifier"
<!-- If Mode attribute is set to Always asynchronous postbacks triggered within the region update its contents automatically;
If it is set to Conditional the region is updated in response to a registered trigger -->
Mode="Always|Conditional"
<!-- If RenderMode attribute is set to Block the content within the UpdatePanel is rendered using a <DIV> element;
If it is set to Inline a <SPAN> element is used as a container for the content within the UpadatePanel -->
RenderMode="Block|Inline"
runat="server">
<ContentTemplate>
<!-- Content to be rendered within the region-->
</ContentTemplate>
<!a€”A Collection of objects that trigger an asynchronous update on the panel. These Objects don't need to be declared within the region. -->
<Triggers>

<ControlValueTrigger
ControlID="object instance identifier"
PropertyName="property value that triggers the update"/>
<ControlEventTrigger
ControlID="object instance identifier"
EventName="the name of the event that triggers the update"/>
</Triggers>
</atlas:UpdatePanel>

· TimerControl:它在客戶端生成一個定時器,由該客戶端以指定的時間間隔觸發異步回饋。該控件通常用作一個要求定時更新內容的UpdatePanelat控件的觸發器控件。為了以聲明方式定義這個控件,需要使用下列語法:

<atlas:TimerControl Enabled="boolean true or false" ID="Control instance identifier"
<!--If the Enabled property is set to true the control is defined on the client-side. If not it isn't.-->
Interval="Interval in milliseconds. the default is 60000."
OnTick="invoked server-side event handler name" runat="server"/>

· Extender控件:它們使用增加的客戶端功能擴展asp.net控件。例如,AutoCompleteExtender控件支持asp.net文本框控件的自動完成行為,而DragOverlayExtender控件支持拖動行為。

· 開發者還可以使用一個與Atlas控件工具箱一同提供的Visual studio 2005工程模板創建定制的asp.net Atlas控件擴展器。

(二) 客戶端庫

客戶端庫包括一組(.js)JavaScript文件,它們被打包為Microsoft.Web.Atlas.dll裝配集中的資源。
包含在這個類庫中的對象提供了下列特征:

· JavaScript語言擴展:允許開發者以JavaScript編程,而同時還能使用使用OO結構,例如命名空間、類、枚舉、接口和數據類型。

· JavaScript基庫擴展:這包括用于調試,跟蹤和字符串操作的其它對象。

· 瀏覽器兼容性:對于定制腳本和由Atlas控件生成的腳本的自動瀏覽器可移植性。

· 網絡功能:由位于Sys.Net命名空間內部的對象提供。這些功能使得與主機的異步通訊和執行遠程方法的編程相當容易。

· HTML控件包裝器:它們允許開發者使用xml腳本添加特征—例如數據綁定,行為以及到許多HTML控件和元素的動作。

· Atlas客戶端控件:支持開發者使用JavaScript或XML腳本創建豐富的應用程序;這些包括在Sys.UI.Data命名空間內部的控件,例如ListView,DataNavigator,ItemView,XSLTView,等等。

· Xml-Script:一個聲明性腳本模型,它允許開發者使用一種類似于asp.net的編程模型書寫客戶端代碼。Atlas聲明性腳本被使用下列語法定義在<script></script>標簽內部:

<script type="text/xml-script">
<page xmlns:script="http://schemas.microsoft.com/xml-script/2005">
<references>
</references>
<components>
</components>
</page>
</script>

整個客戶端庫都包含在Atlas.js文件中,并且當在一個頁面中定義一個ScriptManager控件時被默認地參考。另外地,為了減少在客戶端生成的腳本的數量,我們可以把ScriptManager控件的EnableScriptComponents設置為false并且使用包含在AtlasRuntime.js文件中的該庫的一個簡化版本。另外,專門的庫文件,例如AtlasDragandDrop.js,AtlasUIMap.js,AtlasUIGlitz.js等等,都可以按名使用ScriptManager控件的腳本集合屬性進行引用。

五、 Mash-up和Gadget(widget)

Atlas中引入了兩種新的特征:橋接技術和gadget。橋接技術允許Web應用程序消費來自多種遠程Web服務的數據—當連接到一個單一的主機上時。這些消費一個或更多的遠程服務的Web應用程序通常被稱作是Mash-up。為了實現這一目的,該框架引入了橋接文件,以.asbx擴展名標志。其實,橋接文件是XML文件—允許我們以聲明方式來定義到服務的連接并實現數據轉換。下圖4展示了一個通過Atlas橋接技術消費(mashing-up)來自多種遠程Web服務上的數據的Web應用程序:

點擊放大此圖片
圖4.消費來自多種遠程服務的數據

對于不同的平臺存在不同類型的gadget。一個基于web的gadget是一個可移植的web應用程序—能夠被發布到任何gadget宿主網站上,例如,live.com或start.com。一個基于web的gadget的組成如下:

· 一個Xml聲明:它包含該gadget本身的信息(標題,描述,出版商,構建信息,等等)以及到該gadget組件的鏈接(.jss和.css文件)。下列是一個針對一個虛構的gadget(widget)的示例manifest文件:

<?xml version="1.0" ?>
<rss version="2.0" xmlns:binding="http://live.com">
<channel>
<title>Widget alpha</title>
<link>http://www.contoso.com</link>
<description>What does this gadget do?</description>
<language>en-gb</language>
<pubDate>Date</pubDate>
<!--Javascript function entry point; used by the host to load the gadget . -->
<binding:type>Widget.alpha</binding:type>
<item>
<description>The JavaScript code component</description>
<link>http://www.contoso.com/Gadgets/Widget/alpha.js</link>
</item>
<item>
<description>This adds style to the gadget</description>
<link>http://www.contoso.com/Gadgets/Widget/alpha.css</link>
</item>
</channel>
</rss>

· JavaScript代碼:包含在該manifest文件鏈接到的.js文件中;它定義將被宿主的可移植組件。

· 式樣表:它定義主機用來生成上面gadget的式樣。

六、 測試驅動的框架

本文將在asp.net應用程序中使用Atlas UpdatePanel控件和部分頁面生成技術。

這里所提供的示例是一個Amazon電子商務服務Web客戶端應用程序,它使用City,Cuisine和Neighbourhood搜索參數來搜索在整個美國的餐館。該示例應用程序使用了一個UpdatePanel控件來進行異步回饋和部分頁面生成;從而使應用程序更為迅速和更具交互性以改進用戶體驗。

(一) 需求

· 微軟Visual Studio 2005,.Net框架2.0及最新的Atlas CTP。

· 注冊(免費)Amazon Web服務以取得存取鍵ID—用它來存取該電子商務服務。

(二) 配置網站

通過使用與框架的CTP一起安裝的Atlas工程模板創建一個新的網站:

1. 打開Visual studio 2005。

2. 點擊“文件”菜單,選擇“新建”,然后點擊Website。

3. 從“New Web site”對話框中選擇“Atlas project”模板,位置,工程名和開發語言(VB或C#)。本例中所使用的語言為C#。

下面的圖5顯示了在Visual Studio 2005中的“New Web Site”對話框。


圖5.“New Web Site”對話框窗口

(三) 為SOAP請求配置服務

1. 登錄到你使用Amazon Web服務創建的帳戶并且使用提供的鏈接來保存到你的計算機上的WSDL文件中。

2. 從.Net框架2.0 SDK命令提示窗下使用WSDL.exe工具為你在第1步保存的WSDL中的服務生成一個代理類:

Wsdl <options> <URL | path>

3. 從你用Visual Studio創建的工程中打開Solution Explorer窗口,并右擊工程文件,指向“Add asp.net”文件夾并且點擊“App-Code”。

4. 右擊Solutions Explorer窗口中的“App-Code”文件夾并且點擊“Add Existing Item”。

5. 從“Add Existing Item”對話框中瀏覽到你前面所創建的代理文件,選擇它并且點擊“Add”;這將把服務代理文件添加到工程中。

(四) 創建客戶端UI

1. 在Solutions Explorer中,雙擊Default.aspx文件,從而在Visual Studio designer窗口中打開它。

2. 請確保你位于源碼視圖中,然后在文檔的<form id="form1" runat="server">和</form>之間復制并粘貼下列代碼:

<atlas:ScriptManager ID="ScriptManager1" EnablePartialRendering="true" runat="server" EnableScriptComponents="true"/>
<asp:Label ID="Label1" runat="server" Width="366px" Font-Bold="True" Font-Names="Verdana Ref" Font-Size="Small" Height="19px">SEARCH FOR RESTAURANTS WITH AMAZON.COM</asp:Label><br />
<br />
<asp:Label ID="Label2" runat="server" Text="Access Key ID:" Width="128px" Font-Names="Verdana Ref"></asp:Label>
<asp:TextBox ID="TxtBAccessKey" runat="server" Width="182px" Font-Names="Verdana Ref"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="*"
Width="16px" ControlToValidate="TxtBAccessKey"></asp:RequiredFieldValidator><br />
<asp:Label ID="Label3" runat="server" Text="Cuisine:" Font-Names="Verdana" Width="58px"></asp:Label>
<!--The ListBoxCuisine ListBox holds all possible entries for the Cuisine parameter supported by the amazon ECS-->
<asp:ListBox ID="ListBoxCuisine" runat="server" Rows="1" Width="206px" OnSelectedIndexChanged="ListBoxCuisine_SelectedIndexChanged" Font-Names="Verdana Ref" AutoPostBack="True">
<asp:ListItem Text="American cuisine" Value="American cuisine"></asp:ListItem>
<asp:ListItem Text="Asian cuisine" Value="Asian cuisine"></asp:ListItem>
<asp:ListItem Text="Seafood" Value="Seafood"></asp:ListItem>
<asp:ListItem Text="Greek" Value="Greek"></asp:ListItem>
<asp:ListItem Text="Indian" Value="Indian"></asp:ListItem>
<asp:ListItem Text="Italian" Value="Italian"></asp:ListItem>
<asp:ListItem Text="Japanese" Value="Japanese"></asp:ListItem>
<asp:ListItem Text="Chinese" Value="Chinese"></asp:ListItem>
</asp:ListBox>
<br />
<asp:Label ID="Label5" runat="server" Font-Names="Verdana" Text="City:"
Width="61px">
</asp:Label>
<!a€”The Amazon E-Commerce Service supports only the cities defined as list items of the ListBox control-->
<asp:ListBox ID="listBoxCity" runat="server" Height="19px" Width="221px" AutoPostBack="True" EnableTheming="False" Rows="1" OnSelectedIndexChanged="listBoxCity_SelectedIndexChanged" Font-Names="Verdana Ref" >
<asp:ListItem Text="Seattle" Value="Seattle"></asp:ListItem>
<asp:ListItem Text="Boston" Value="Boston"></asp:ListItem>
<asp:ListItem Text="San Francisco" Value="San Francisco"></asp:ListItem>
<asp:ListItem Text="New York" Value="New York"></asp:ListItem>
<asp:ListItem Text="Washington, D.C." Value="Washington, D.C."></asp:ListItem>
<asp:ListItem Text="Chicago" Value="Chicago"></asp:ListItem>
</asp:ListBox>
<br />
<asp:Label ID="Label6" runat="server" Font-Names="Verdana Ref" Text="Neighbourhood:" Width="59px">
</asp:Label>
<asp:TextBox ID="TextBox3" runat="server" Width="143px" Font-Names="Verdana Ref">
</asp:TextBox>
<asp:Button id="submitSearch" runat="server" Height="23px" Text="Submit"
Width="54px" OnClick="submitSearch_Click" Font-Names="Verdana Ref" />
<br />

3. 切換到設計視圖;設計器應該生成如圖6所示的UI。


圖6.示例應用程序的UI

(五) 配置UpdatePanel控件

1. 切換到源碼視圖;在標注后面的<br和/>標簽之間添加下列代碼:

<atlas:UpdatePanel ID="UP1" EnableViewState="true" Mode="Conditional" RenderMode="Inline" runat="server">
<ContentTemplate>
</ContentTemplate>
<Triggers>
</Triggers>
</atlas:UpdatePanel>

當觸發一個已注冊的控件中的事件時,UpdatePanel控件被有條件地進行更新。注冊的事件在服務器端被通過異步回寄處理。

2. 在UpdatePanel控件的<ContentTemplate>和</ContentTemplate>元素之間,加入下面的標注:

<atlas:UpdateProgress>
<ProgressTemplate >
<asp:Label ID="Label4" runat="server" Font-Names="Verdana Ref" Font-Size="X-Small"
Text="Loading..." Width="81px"></asp:Label>
</ProgressTemplate>
</atlas:UpdateProgress>
<br />
<asp:Repeater ID="RP1" runat="server">
<ItemTemplate>
</ItemTemplate>
</asp:Repeater>

<asp:Label ID="NoResults" runat="server" Width="449px" Font-Names="Verdana Ref" ></asp:Label>
<br /> <br />
<asp:Label ID="PriceRange" runat="server" Font-Names="Verdana Ref" Font-Size="X-Small">
</asp:Label>
<br />
<br />
<asp:Label ID="labelError" runat="server" Width="451px" Font-Names="Verdana Ref">
</asp:Label>

當正在更新區域時,UpdateProgress控件顯示一個忙指示器(“加載中……”)。

Repeater和Label控件負責存儲搜索結果及潛在的錯誤消息結果。

3. 為了注冊將觸發部分更新的控件,把下列代碼片斷放到UpdatePanel控件的<Triggers>和</Triggers>元素之間:

<atlas:ControlEventTrigger ControlID="submitSearch" EventName="Click" />
<atlas:ControlEventTrigger ControlID="listBoxCity" EventName="SelectedIndexChanged" />
<atlas:ControlEventTrigger ControlID="listBoxCuisine" EventName="SelectedIndexChanged" />

(六) 在客戶端應用程序添加代碼

切換到設計視圖,雙擊生成的Web表單以顯示頁面相應的代碼部分(Default.aspx.cs)。選擇Ctrl+A來選擇所有的自動生成的代碼,并按Delete鍵清除文檔。然后,添加下列代碼以消費Amazon ECS服務并且顯示搜索結果:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class _Default : System.Web.UI.Page
{
protected AWSECommerceService AmazonECS = new AWSECommerceService();
protected ItemSearch Search = new ItemSearch();
protected ItemSearchRequest SearchRequest = new ItemSearchRequest();
protected ItemSearchResponse SearchResponse;
protected void submitSearch_Click(object sender, EventArgs e)
{
Search.AWSAccessKeyId = TxtBAccessKey.Text.ToString();
SearchRequest.SearchIndex = "Restaurants";
SearchRequest.Cuisine = ListBoxCuisine.SelectedValue;
SearchRequest.City = listBoxCity.SelectedValue;
SearchRequest.Neighborhood = TextBox3.Text.ToString();
SearchRequest.ResponseGroup = new String[] { "ItemAttributes" };
Search.Request = new ItemSearchRequest[1] { SearchRequest };
try
{
SearchResponse = AmazonECS.ItemSearch(Search);
if (SearchResponse.Items == null)
{ labelError.Text = "A Server error has occured."; }
else
{
Items responseItems = SearchResponse.Items[0];
Item[] response = responseItems.Item;
if (response != null)
{
foreach (Item I in response)
{
NoResults.Text = "";
Label Results = new Label();
Label Sep = new Label();
Results.Text = "<strong>" + I.ItemAttributes.Title.ToUpper() + "</strong>" + "<br/>"
+ I.ItemAttributes.Address.Address1.ToString() + "<br/>"
+ I.ItemAttributes.Neighborhood + "<br/>"
+ "Tel:" + " " + I.ItemAttributes.PhoneNumber + "<br/>"
+ "Price Rating:" + " " + priceRating(I.ItemAttributes.PriceRating)+"<br/>"+"<br/>";
Sep.Text = "<br/>";
RP1.Controls.Add(Results);
RP1.Controls.Add(Sep); }
PriceRange.Text ="Price per person (based on entree, appetizer or salad, one non-alcoholic drink plus tax and tip)";
}
else
{
NoResults.Text = "No search results found.";
PriceRange.Text = "";
}
}
}
catch (Exception ex)
{
labelError.Text = ex.Message.ToString();
}
}
private string priceRating(string str)
{
if (str=="1"){
return "under $15";}
else if(str=="2"){
return "$15-30";}
else if(str=="3"){
return "$30-45";}
else if(str=="4"){
return "over $45";}
else{return null;}
}
protected void listBoxCity_SelectedIndexChanged(object sender, EventArgs e)
{}
protected void ListBoxCuisine_SelectedIndexChanged(object sender, EventArgs e)
{}
}

(七) 運行應用程序

1. 為了運行應用程序,在設計視圖下打開Default.aspx頁面。選擇TxtBAccessKey TextBox控件;在Properties窗口中把你的Amazon Web服務存取鍵ID添加到該控件的Text屬性中。

2. 按F5鍵以運行該應用程序。

3. 使用應用程序的過程是相當直接的。從Cuisine:列表框中選擇一種cuisine類型,從City:列表框中選擇一個城市,然后點擊Submit按鈕。作為選擇,你還可以細化你的搜索。

(八) 從瀏覽器中使用Amazon ECS Web服務

1. 使用一個橋接文件來指定消費遠程Web服務的代理類、調用該服務的方法以及如何操作返回的數據。

2. 使用ScriptManager控件參考橋接文件。

3. 使用html控件,JavaScript和客戶端Atlas數據組件來使用服務即可。

七、 結論

Asp.net Atlas是一個創建基于客戶端的Web應用程序的框架。這個框架在提供客戶端和服務器端API用來創建跨瀏覽器兼容的AJAX風格的應用程序的同時,還引入了另外一些特征,例如橋接技術,gadget,一個JavaScript聲明性腳本模型和擴展,等等。

總之,本文介紹了該框架的典型使用框架;還通過使用Atlas UpdatePanel控件介紹了部分(Partial)頁面生成技術,這是在asp.net Web應用程序中增加AJAX功能和改進用戶體驗的最簡單的方法。
作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗