MSDN 程式開發講座:

Atlas Framework 快速上手體驗

作者:奚江華

本頁內容

前言

*
範例程式 collapse menu

*
* *

在上一期「微軟 ASP.NET 2.0 的 AJAX 利劍 ~ Atlas Framework」文章中,筆者已介紹 AJAX 初步概念與 Atlas Framework 藍圖,相信許多人對 AJAX 非同步能力可能非常好奇,而微軟非同步技術 Atlas Framework 又將為網頁開發帶來什麼不一樣的新局面呢?為了一窺這美麗新殿堂,筆者將引領您上手五個實際範例 Labs,目前所有的 Atlas Framework 文章及範例只有英文的,因為就連美國亦才剛風起雲湧這股 AJAX 新浪朝,而筆者責任就是替各位 Study 最困難的部分,再轉化成淺顯易懂的說明,讓大家輕鬆學習上手。

雖然只有區區五個範例,但總頁數卻多達 83 頁,沒人指導想要自行練習坦白說並不容易,其中困難點包括了 (1) 英文理解力 (2) AJAX 非同步概念 (3) Master Page 觀念技巧 (4) Beta 版等因素,常閱讀英文技術文章的朋友一定很能體會一點,就是對於閱讀主題若沒有基本背景知識或 Sense,即便每字每句都看得懂,步驟說明也很明瞭,但是全篇看完還是不知道它在講什麼,今年 9 月份國內還沒什人麼談 Atlas Framework 時,我利用週末假日在辦公室裡 K 這生冷的技術文件就是這種感覺,第一個上手範例就花掉我三個小時逐字逐句讀,一個步驟一個步驟做,小心翼翼一個 Tag 一個 Tag 的打還是失敗,就連用肉眼仔細除錯也徒勞無功,挫折感不可謂不大,但最後還是成功了,怎麼辦到的?呵呵…就是 Copy & Paste,哇~會不會太遜了,但即便是 Copy & Paste 也要知道要複製哪段關鍵程式碼才能成功,因為你在 Coding 當中若有錯誤 VS 2005 並不會警告你,甚至是 Intellisense 對其支援也很薄弱,原因是 Atlas Framework 是在今年 6 月份美國微軟 Web 平台及工具經理 Scott 突然宣布要加入這個 Framework,之所以如此突然是因為 AJAX 勢力迅速竄紅,微軟能夠及時抓住這股風潮策略是對的,否則等所有競爭者的 AJAX Framework 都齊備了,頓時就會變成後知後覺的落後者,再要追趕可能就比較辛苦,好啦廢話不多說,以下直接進入實際上手範例講解。

Atlas Framework系統環境設定

(一)Atlas Framework下載

由於最近微軟才更新 12 月份最新安裝套件,這個最新的預覽版已不支援 Hands-On Lab 了,故請使用本期文章所附的兩個套件。若正式版發行後您可以到微軟網站 Http://Atlas.asp.net 下載 Atlas Framework 套件,在網頁右側中可以看到兩個套件 (1) Atlas Blank Project VSI (2) Atlas Hands-On-Lab VSI,這兩個VSI有什麼分別呢?本質上是一模一樣的,差異在於 Hands-On-Lab VSI 裡面含有範例所需的資料檔、背景圖片與 Lab 文件等檔案,為了省事的緣故,請將這兩個檔一併安裝,而實際上手範例將會以 Atlas Hands-On-Lab 這個樣板為主;此外 Atlas Framework 套件同時適用於 VS 2005 及 Visual Web Developer 2005 Expression 兩種版本。


圖 1 Atlas Framework 套件下載

(二)系統安裝

下載完成後請直接進行安裝動作,安裝時系統若出現警告訊息則不予以理會(圖 2),當安裝完成後(筆者是以 Administrator 帳號登入),在電腦路徑 C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Templates\ProjectTemplates\Visual Web Developer\Csharp 中會產生兩個對應的樣板檔案 ASPNETAtlasWebApplicationCS.zip 與 ASPNETAtlasHOLCS.zip(VB.NET 則為 C:\Documents and Settings\Administrator\My Documents\Visual Studio 2005\Templates\ProjectTemplates\Visual Web Developer\VisualBasic 路徑下 ASPNETAtlasWebApplicationVB.zip 與 ASPNETAtlasHOLVB.zip)。


圖 2 安裝警告訊息

(三)移除舊版本 Atlas Framework

若您之前曾經安裝過任何預覽版的 Atlas Framework 套件,同樣的也先到上面路徑將其樣板檔案全部刪除後再重新安裝,否則同時安裝多個新舊版本會導致 VS 2005 可能誤用舊版本而發生錯亂(圖 3),甚至還可能連 Compile 都過不了關,因為不同版本間其功能有做修改。


圖 3 Atlas Framework 套件新舊版本重複安裝畫面

註:在預設路徑中的様板檔案可以任何 Copy、Delete 或備份,因為它只是單純的檔案型態,並不會對 VS 2005 造成損害,故請放心。

(四)安裝 SQL Server 或 Access 北風資料庫

雖然微軟原始五個上手範例並沒有使用到 SQL Server 或 Access 資料庫,但為了讓各位體驗 Atlas Framework 非同步的威力,筆者針對 Lab 練習做了小幅修改,示範非同步如何結合北風資料庫的存取來展示其優勢,如此較能夠有更深刻的體認;倘若您沒有北風資料庫則請自行匯入,或將程式改寫以自己的資料庫來替換。

(五)範例程式原始檔案

筆者本期文章講解是以 C# 程式碼為主,但為了幫助 C# 與 VB.NET 讀者都能夠實際上手體驗 Atlas Frameowrk,故程式檔同時提供 VB.NET 與 C# 兩個版本。

範例說明

微軟目前推出五個 Hands-On Labs 供大家練習實作,先說明一下這五個範例是在做什麼,大家心裡有個底之後做起來也比較順手,說明如下:

(一) Lab 1:Creating a Basic ASP.NET "Atlas" Web Application

Lab1 是第一個 Atlas Framework 範例,其目的在於示範基本的 Atlas 技巧,透過在 WebForm 中的 TextBox 輸入員工姓名,經由 AJAX 非同步技術呼叫 Server 端的 Web Service,而 Web Service 回傳員工基本資料,最後自動更新在頁面上。

(二) Lab 2:Creating a Declarative Web Application with ASP.NET "Atlas"

Lab2 是將 Lab1 範例以 Atlas 宣告式語法來撰寫,它是使用 Client 端 Atlas UI Control 方式來達成和 Lab1 一樣的功能。

(三) Lab 3:Creating an Auto-completion TextBox with ASP.NET "Atlas"

Lab3 主要是展示 Web 的自動完成 TextBox,這是許多人想要的功能,透過 Client 端 Atlas UI 與 JavaScript 兩者搭配來實現自動完成的目的。

(四) Lab 4:Using ASP.NET "Atlas" Auto-completion with a Server Control

Lab4 則是 Lab3 自動完成更進階的簡化,透過二行 Atlas 伺服器控制項的宣告即可做到自動完成功能,比 Lab3 用 Client 端技術更為簡潔俐落。

(五) Lab 5:Creating an "Atlas" Web Aplication Data-binding and Template

範例

Client 端/Server 端技術

Lab 1 Client 端 JavaScript
Lab 2 Client 端 Atlas UI 與 JavaScript
Lab 3 Client 端 Atlas UI 與 JavaScript
Lab 4 Server 端 Atlas 控制項與 ScriptManager
Lab 5 Server 端 Atlas 控制項與 ScriptManager
表格一 五個 Labs 範例技術說明表

建立 Atlas Hands-on Lab 專案

請在 VS 2005 IDE 工具中建立 Web 專案,選擇「ASP.NET ' Atlas ' Hands-On-Lab Web」樣板,並命名為「AtlasFramework」,而後續的五個 Labs 都在這個專案中建置。


圖 4 建立 AtlasFramework 專案

練習建議

在此給想要練習體驗 Atlas Framework 非同步技術力量的朋友,如果你屬於下列幾種情形者,建議先用複製並貼上程式碼方式來進行:

  • 不懂 Master Page 運作原理。
  • 不懂 JavaScript 技術。
  • 因 VS 2005 的除錯、Intellisense、編譯器支援極為有限,若你程式 Key-in 容易字誤者,也建議利用複製並貼上,因為錯誤將會難以偵錯。

以上幾點都是阻礙您體驗 Atlas Framework 威力的障礙,故強烈建議全程以複製並貼上程式碼方式來進行,待程式 RUN 成功後,再回頭一一拆解程式是如何辦到的,或者再自行重新逐字 Key-in,如此比較容易上手又不會有太多挫折感。

註:或是下載使用筆者所附的 Web 專案程式檔,直接拿來使用會更快。

實際範例講解

Atlas 五個範例皆以 In-Line Code 的方式進行,因為目前 VS2005 不認得 Atlas Framework 的 Schema,故尚無法有效支援 Code Behind 的 IntelliSense 方式撰寫。

(一)範例一 建立基本的ASP.NET Atlas 網頁應用程式

如果你曾經依照微軟英文 Hands-On Lab 文件練習過,有可能會如墜五里霧中,因為範例步驟說明切得過於零碎,故筆者將本範例稍加整理得較為易懂,但是由於原始範例功能太過簡化,並且有兩個小缺失 (1) 有 Button Click 動作 (2) 只回傳系統時間不夠貼切,因此對於初次接觸 AJAX 或 Atlas Framework 的朋友可能會分不清這樣的東西到底能幹嘛?跟原來 Postback 技術好像差異不大,為了讓各位瞭解二者之間的真正差異,我將範例稍做改寫:(1)在 Client 端加入每秒鐘自動呼叫後端 Web Service 的 JavaScript 指令,以 TextBox 中輸入的姓名當做參數傳給 Web Service (2) 後端 Web Service 透過 ADO.NET 查詢 Northwind 北風資料庫,傳回相符的使用者個人詳細資料(3)最後索性連 Button 按鈕都捨棄,讓您更能體會什麼是 AJAX 非同步技術。

本範例是用傳統的 JavaScript 以非同步的方式呼 Web Service,而這個 Web Service 會以 ADO.NET 查詢北風資料庫中的 Employees 員工資料表,並且將符合條件的員工資料回傳給 Client 端畫面顯示。

雖然簡化來講只是在做 Client 端與 Server 端兩個部分,但總共可分為三個步驟,以下是說明(建議全程以複製並貼上程式碼來進行,純粹體驗 Atlas 威力):
Step 1:建立 Master Page
這個 Master Page 將會被前四個範例所使用到,Default.master 其程式碼如下:

<%@ Master Language="C#" %>

<!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" xml:lang="en" lang="en">
<head id="Head1" runat="server">
    <asp:contentplaceholder runat="server" ID="ScriptIncludes">
      <atlas:script id="Script1" runat="server" Path="~/ScriptLibrary/AtlasCompat.js" Browser="Mozilla" />
      <atlas:script id="Script2" runat="server" Path="~/ScriptLibrary/AtlasCompat.js" Browser="Firefox" />
      <atlas:script id="Script3" runat="server" Path="~/ScriptLibrary/AtlasCompat.js" Browser="AppleMAC-Safari" />
      <atlas:script id="Script4" runat="server" Path="~/ScriptLibrary/AtlasCore.js" />
      <atlas:script id="Script5" runat="server" Path="~/ScriptLibrary/AtlasCompat2.js" Browser="AppleMAC-Safari" />
    </asp:ContentPlaceHolder>
    <link rel="stylesheet" type="text/css" href="site.css" />
    <asp:contentplaceholder runat="server" ID="Head" />
</head>
<body>
    <asp:contentplaceholder id="Main" runat="server">
    </asp:contentplaceholder>
</body>
</html>

程式說明:
(1) 各位可以看到 Master Page 裡面引入了一堆 <Atlas:Script>,其目的是為了達成瀏覽器(跨平台)相容性,不必為了不同瀏覽器而必須撰寫數套網頁程式,請回想第一期文章曾談到:「Libraries 函式庫會自動處理不同瀏覽器的相容性問題,免除了撰寫特定瀏覽器的 Scripts 的必要性。」因此從這點就可以察知 Atlas Framework 不是隨便說說畫大餅而已,確實是依據當初所規劃的藍圖在進行。

(2) 而 ScriptLibrary 則是改良過的 JavaScript 函式庫,支援繼承、封裝、介面等諸多物件導向的特性,是 Atlas Framework 程式運作非常重要的一部分

(3) Master Page 並非是必要的,只不過是借用 Master Page 機制而達成加入 Atlas Script 及佈景主題的目的。


圖 5 Master Page 畫面

Step 2:建立 Lab1.aspx 內容頁程式
建立使立使用 Master Page 的 Lab1.aspx 內容頁,裡面主要有 Text 輸入與訊息顯示,外加三個 JavaScript Function,同時參照了 EmployeeService.asmx 網路服務,程式如下:

<%@ Page Language="C#" MasterPageFile="Default.master" Title="Atlas HOL 1" %>

<asp:Content ID="Content3" ContentPlaceHolderID="Main" Runat="Server">

  <form action="">
    <div>
      員工姓名:
      <input id="inputName" type="text" />
    </div>
  </form>
  <hr style="width: 300px" />
  <div>
    <span id="Results"></span>
  </div>
  <script type="text/JavaScript" src="EmployeeService.asmx/js">
  </script>
  
  <script type="text/JavaScript">
    function DoSearch()
    {
      var SrchElem = document.getElementById("inputName");
      Samples.AspNet.EmployeeService.Employee(SrchElem.value, OnRequestComplete);
    }

    function OnRequestComplete(result) 
    {
      var RsltElem = document.getElementById("Results");
      RsltElem.innerHTML = result;
    }
    
    setInterval('DoSearch()',1000);
  </script>
</asp:Content>

程式說明:
原先的範例中有 Button 按鈕,但筆者為了讓各位更真實體驗到什麼是 AJAX 非同步技術,刻意將 Button 按鈕拿掉。

Step 3:建立 EmployeeService.asmx 網路服務
本程式作用是將員工基本資料回傳給前端,前端收到後會自動進行畫面更新,而程式內是透過 ADO.NET 來查詢北風資料庫中 Employees 資料表的 Web Service。

<%@ WebService Language="C#" Class="Samples.AspNet.EmployeeService" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Data;
using System.Data.SqlClient;

namespace Samples.AspNet {

    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class EmployeeService : System.Web.Services.WebService
    {
        [WebMethod]
        public string Employee(String txtFirstName)
        {
            SqlConnection conn = new SqlConnection("data source=.;initial catalog=Northwind;user id=sa;password=test");
            conn.Open();

            SqlCommand cmd = new SqlCommand("select EmployeeID,FirstName,City,Address from Employees where 
FirstName=@FirstName", conn); cmd.Parameters.Add("@FirstName", SqlDbType.NVarChar, 10).Value = txtFirstName; SqlDataReader dr = cmd.ExecuteReader(); string txtMsg = ""; if (dr.Read()) { txtMsg = "員工代號:" + dr["EmployeeID"] + " ,"; txtMsg += "姓名:" + dr["FirstName"] + " ,"; txtMsg += "居住城市:" + dr["City"] + " ,"; txtMsg += "地址:" + dr["Address"] + " ,"; } else { if (String.IsNullOrEmpty(txtFirstName)) { txtMsg = "<Font Color='Blue'>請輸入姓名</Font>"; } else { txtMsg = "<Font Color='Red'>查無此人!</Font>"; } } cmd.Dispose(); dr.Dispose(); conn.Dispose(); return txtMsg; //回傳使用者詳細資料 } } }

程式說明:
(1) 以上是一個典型的 ADO.NET 資料庫程式,以 TextBox 所輸入的 FirstName 當做參數向資料庫查詢,並將相符的結果回傳給前端。

(2) 資料庫帳號密碼請自行修改成您練習環境的資料庫帳號密碼。


圖 6 北風資料庫參考畫面

故各位可以隨意輸入 Nancy、Steven 或 Robert 等員工 FirstName 姓名測試一下,畫面自動就會將員工基本資料回傳。


圖 7 Lab1 員工基本資料查詢結果

Lab1 是建立基本的 ASP.NET Atlas 網頁應用程式,基本上是在做二件事:

  • 建立 Client 端展現的 ASP.NET 網頁(使用 Master Page)。
  • 建立 Server 端的 Web Service。

各位大致看一下筆者整理的關係圖就會明白其中運作的原理了,有的人可能會心想 Lab1.aspx 明明就是屬於 Server 端的東西,怎麼被筆者硬抝劃分到 Client 端?各位不要忘了,不管是 ASP.NET、PHP 或 JSP 最終都會被 Render 成前端瀏覽器可以呈現的 HTML 格式,且頁面也是透過前端 JavaScript 來做非同步觸發動作,所以圖並沒有畫錯。


圖 8 Lab1 非同步模式運作關係圖

(二)範例二 以 Atlas 宣告式語法建立網頁應用程式

在 Lab1 是使用純 HTML 語法及 JavaScript 來進行非同步處理,而 Lab2 範例是將 Lab1 改寫成使用 Atlas 宣告式語法,以 <component> element 宣告,並且呼叫相同的 EmployeeService.asmx 網路服務來回傳員工基本資料,以下是 Lab2.aspx 程式碼:

<%@ Page Language="C#" MasterPageFile="~/Default.master" Title="Atlas HOL 2" %>

<asp:Content ID="Content3" ContentPlaceHolderID="Main" runat="Server">

<form action="">
  <div>
    員工姓名:
    <input id="inputName" type="text" />
    <input id="btnQuery" type="button" value="查詢" />
  </div>
</form>
<hr style="width: 300px"/>
<div>
  <span id="Results"></span>
</div>
<script type="text/xml-script">
  <page xmlns:script="http://schemas.microsoft.com/xml-script/2005">
    <references>
      <add src="ScriptLibrary/AtlasUI.js" />
      <add src="ScriptLibrary/AtlasControls.js" />
    </references>
    <components>
      <textBox id="inputName" />
      
      <button targetElement="btnQuery">
        <click>
          <invokeMethod target="EmployeeService" method="invoke" />
        </click>
      </button>
      
      <serviceMethod id="EmployeeService" url="EmployeeService.asmx"  methodName="Employee">
        <bindings>
          <binding dataContext="inputName" dataPath="text" property="parameters" propertyKey="txtFirstName" />
        </bindings>
        <completed>
          <invokeMethod target="resultsBinding" method="evaluateIn" />
        </completed>
      </serviceMethod>
            
      <label targetElement="Results">
        <bindings>
          <binding id="resultsBinding" dataContext="EmployeeService" dataPath="response.object" 
property="text" automatic="false" /> </bindings> </label> </components> </page> </script> </asp:Content>

程式說明:
第一次接觸上面的語法可能有點難接受,甚至看不懂中間的程式脈絡在做什麼東西,盡是一些"亂七八糟"的語法,難道不能更簡潔更容易理解嗎?放心我已先替各位做功課了,並且理出的程式關係圖及說明,以下是 Atlas 宣告式語法基本形式:

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

    <components>
	....
    </components>
  </page>
</script>

上面是 Atlas Client 端的 UI Control 宣告,<script type="text/xml-script"> element 是用來供系統識別 Atlas 宣告式語法,裡面是屬於 XML 語法形式,而 <page> 是 XML 的根節點,裡面主要包含二個 elements:

1. <references> element 是用來加入 Atlas Framework 的 Client Script Library 參考,裡面包含了 Atlas Framework 運作所必須的 JavaScript。


圖 9 Atlas ScriptLibrary


圖 10 參照 Atlas Script Library

2. <components> element 則是屬於 Atlas UI components 的宣告,裡面則包含了子節點宣告,在解釋其完整意義之前,請看下面筆者整理的運作關係圖:


圖 11 Atlas UI Component 運作關係圖

透過上面的關係圖流程就可以大致瞭解其運作流程,首先由於在 HTML 中建立了 TextBox 輸入與 Button 按鈕二個控制項,故相對的在 Atlas UI Component 也必須宣告其對應關係,接著輸入姓名後按下查詢按鈕,則其透過 <bindings> 來進行 Web Service 呼叫,Web Service 查詢資料庫後會回傳結果給 <completed>,而後 <completed> 會在其對應的 <label> 進行資料繫結動作,最後將員工資料顯示在 <span> 之中。解釋完上面的運作關係及流程後,原本對其雜亂無章的印象突然為之改觀,甚至會覺得原來其語法是如此嚴謹而有結構性,一掃原本第一眼先入為主的偏見。


圖 12 Lab2 員工基本資料查詢結果

(三)範例三 以 Atlas 宣告式語法建立「自動完成 TextBox」

本範例是使用 Atlas UI及JavaScript 來示範「自動完成 TextBox」功能的建置,使用者只要輸入開頭幾個英文字後就會顯示「自動完成」清單供使用者選取(由 AutoCompleteService.asmx 網路服務提供),選取後再按下查詢按鈕後會呼叫 HelloWorldServer.asmx,並將結果回傳到 <span> 標籤中顯示結果,以下是步驟說明:

Step 1:建立 Atlas UI Control 程式
下面是 Lab3.aspx 程式碼:

<%@ Page Language="C#" MasterPageFile="~/Default.master" Title="Atlas HOL 3" %>

<asp:Content ID="Content3" ContentPlaceHolderID="Main" Runat="Server">

  <form action="">
    <div>
      Search for 
      <input id="SearchKey" type="text" /> 
      <input id="SearchButton" type="button" value="Search" 
        onclick="DoSearch()"/>
    </div>
  </form>

  <div id="completionList"></div>
  <hr style="width: 300px"/>
  <div>
    <span id="Results"></span>
  </div>
  
  <script type="text/JavaScript" src="HelloWorldService.asmx/js">
  </script>
    
  <script type="text/JavaScript">

  function DoSearch()
  {
    var SrchElem = document.getElementById("SearchKey");
    Samples.AspNet.HelloWorldService.HelloWorld(SrchElem.value, 
      OnRequestComplete);
  }

  function OnRequestComplete(result) 
  {
    var RsltElem = document.getElementById("Results");
    RsltElem.innerHTML = result;
  }

  </script>
    
  <script type="text/xml-script">
    <page xmlns:script="http://schemas.microsoft.com/xml-script/2005">
      <references>
          <add src="ScriptLibrary/AtlasUI.js" />
          <add src="ScriptLibrary/AtlasControls.js" />
      </references>
      <components>
          <textBox id="SearchKey">
              <behaviors>
                  <autoComplete 
                    completionList="completionList" 
                    serviceURL="AutoCompleteService.asmx" 
                    serviceMethod="GetWordList"
                    minimumPrefixLength="2" 
                    completionSetCount="15" 
                    completionInterval="500" />
              </behaviors>
          </textBox>
      </components>
    </page>
  </script>
    
</asp:Content>

程式說明:
以下針對 <component> 中 <textBox> 的 <behaviors> 行為屬性做一簡要說明:

  1. serviceURL="AutoCompleteService.asmx" 指示自動完成功能由哪個 Web Service 提供。
  2. serviceMethod="GetWordList" 是指呼叫 AutoCompleteService.asmx 服務的 GetWordList() 方法。
  3. minimumPrefixLength="2" 是最少要輸入 2 個開頭字才會執行自動完成功能。
  4. completionSetCount="15" 是指回傳多少個結果。

completionInterval="500" 是指 500 毫秒,也就是每 0.5 秒就會檢查 TextBox 輸入字串是否合乎條件,以決定是否進行自動完成功能呼叫。

Step 2:建立 AutoCompleteService.asmx 網路服務
這個網路服務是負責提供自動完成功能清單,以下是程式碼:

<%@ WebService Language="C#" Class="Samples.AspNet.AutoCompleteService" %>

using System;
using System.IO;
using System.Web;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Serialization;

namespace Samples.AspNet
{
  [WebService(Namespace = "http://tempuri.org/")]
  [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  public class AutoCompleteService  : System.Web.Services.WebService 
  {
    private static string[] autoCompleteWordList = null;

    [WebMethod]
    public String[] GetWordList(string prefixText, int count)
    {     
      if (autoCompleteWordList == null)
      {
        List<String> words = new List<string>();
        FileStream file = new 
          FileStream(Server.MapPath("~/App_Data/words.txt"), FileMode.Open, 
          FileAccess.Read);
        StreamReader reader = new StreamReader(file);
        String word;
        while ((word = reader.ReadLine()) != null)
        {
          words.Add(word);
        }
        file.Close();
        autoCompleteWordList = words.ToArray();
        Array.Sort(autoCompleteWordList, new CaseInsensitiveComparer());
      }

      int index = Array.BinarySearch(autoCompleteWordList, prefixText, new CaseInsensitiveComparer());
      if (index < 0)
      {
        index = ~index;
      }

      int matchingCount;
      for (matchingCount = 0;matchingCount < count && index + matchingCount < autoCompleteWordList.Length;matchingCount++)
      {
        if (!autoCompleteWordList[index + 
          matchingCount].StartsWith(prefixText, 
          StringComparison.CurrentCultureIgnoreCase))
        {
          break;
        }
      }

      String[] returnValue = new string[matchingCount];
      if (matchingCount > 0)
      {
        Array.Copy(autoCompleteWordList, index, returnValue, 0, 
          matchingCount);
      }
      return returnValue;
    }
      
  }
}

程式說明:
以上 Web Service 程式若看不懂的話不必要緊,只需知道其作用是將 Words.txt 檔案中查詢相符的資料以字串陣列回傳即可,因為 Web Service 並非是 Atlas Framework 技術展示的重點。但是你也可以自行改寫,例如用 ADO.NET 讀取資庫並將查詢結果放入字串陣列之中,再回傳這個陣列即可。


圖 13 Web Service 回傳資料參考畫面

Words.txt 資料檔片段(在 App_Data 目錄下):

…
CLR
CLS
CLS-compliant
code access security
code-behind class
code-behind file
code-behind page
COM callable wrapper (CCW)
COM interop
Common Information Model (CIM)
common language runtime
common language runtime host
Common Language Specification (CLS)
common object file format (COFF)
common type system (CTS)
comparison evaluator
composite control
configuration file
connection
connection point
…

Step3:建立 HelloWorldService.asmx 網路服務
這個網路服務是純粹回傳一個 Hello 之類的訊息,以下是程式碼:

<%@ WebService Language="C#" Class="Samples.AspNet.HelloWorldService" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

namespace Samples.AspNet 
{

  [WebService(Namespace = "http://tempuri.org/")]
  [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  public class HelloWorldService  : System.Web.Services.WebService 
  {

    [WebMethod]
    public string HelloWorld(String query)
    {
      string inputString = Server.HtmlEncode(query);
      if(!String.IsNullOrEmpty(inputString))
      {
        return String.Format("Hello, you queried for {0}. The current time " 
          + "is {1}", inputString, DateTime.Now);
      }
      else
      {
        return "The query string was null or empty";
      }
    } 
  }
}


圖 14 Atlas UI Control 自動完成畫面


圖 15 Atlas UI Control 查詢結果


圖 16 Lab3 運作關係圖

(四)範例四 以 Atlas 伺服器控制項建立「自動完成 TextBox」

範例三 Lab3.aspx 程式已開始顯現 Atlas Framework 不凡的威力,透過 Atlas 宣告式語法即可搞定網頁「自動完成」功能,在一般常見 ASP.NET 技法並無法直接而輕易做到這樣子的功能,雖然 Atlas Framework 已為我們指引一條明路,由無解變有解,或難解變易解,但別忘了人性是貪婪不滿足的,不禁令人要問一句﹕「還可以不可以更簡單?」有沒有自動完成的伺服器控制項可以直接套用了,簡單易用毫不拖泥帶水?(筆者心中亦是如此貪婪地想著),答案是還真的有一組伺服端的「自動完成」控制項供我們隨意取用。本範例就是在示範使用 Server 端的「自動完成」控制項,而後端仍是呼叫 AutoCompleteService.asmx,以下是 Lab4 程式碼:

<%@ Page Language="C#" MasterPageFile="~/Default.master" Title="Atlas HOL 4" %>

<asp:Content ID="Content3" ContentPlaceHolderID="Main" Runat="Server">

<form id="Form1" runat="server">
  <atlas:ScriptManager id="AtlasPage1" runat="server" />
  <div class="page" id="links">
    <div id="content">
      <h3>AutoComplete server control</h3>
      <p>This file contains a server-side Atlas AutoComplete.</p>
      <atlas:TextBox id="searchBox" runat="server"   
AutoCompletionServiceUrl="AutoCompleteService.asmx" 
AutoCompletionServiceMethod="GetWordList" />
    </div>
  </div>
</form>

</asp:Content>

程式說明:
(1) 本程式達成「自動完成」功能嚴格來講只有兩行程式:

01 <atlas:ScriptManager id="AtlasPage1" runat="server" />
02 <atlas:TextBox id="searchBox" runat="server"  
AutoCompletionServiceUrl="AutoCompleteService.asmx" AutoCompletionServiceMethod="GetWordList" />

哇!簡單到令人不可思議,短短二行程式就足以打敗自修苦練三五年的網頁技術,而且還不見得能夠做的出來,Lab4 是五個範例中最能顯現 Atlas Framework 價值與威力的地方,強烈散發出令人一見鐘情的魅力,讓人絲毫無法抗拒,光是這個「自動完成」伺服器控制項就可以解答許多人心中的疑問:「到底 Atlas Framework 值不值得使用?」小心您還再猶豫,一個剛出道的菜鳥工程師只需用兩行程式就可以打敗你了,哪天被人用 Atlas 利劍給宰了都還不自知。可見 Atlas Framework 確實能夠大幅縮短專案開發時程,差別很可能是 10 分鐘對上一個月的時間巨幅落差,事實上這也是國外許多專家都開始紛紛放棄自行撰寫非同步程式的原因,轉而採用 AJAX 之類的 Library 或 Framework,如此可大幅加速 AJAX 應用程式開發工作,將心力投注在商業運作流程核心上,而不是 AJAX 瑣碎的細節上。

許多人一定會這樣想:「若正式版的 Atlas Framework 如果能夠提供一系列如此好用的伺服器控制項該有多好?!」是的,Atlas Framework 目前就已經提供了一系列 Atlas Server 控制項供各位使用,也一步步的強化相關功能,筆者相信在可以預見的未來,使用成熟的 Atlas Framework 就如同喝白開水一樣簡單,只需滑鼠拖拖拉拉再設定幾個屬性就搞定了。

(2) AutoCompletionServiceUrl="AutoCompleteService.asmx" 是指定 Web Service,而 AutoCompletionServiceMethod="GetWordList" 則是指定 Web 服務內的方法。

(3) <atlas:ScriptManager> 則是用於管理 Atlas 伺服器控制項所必須的 JavaScript,當 Page 頁面使用到 Atlas 伺服器控制項時,則伺服器控制項所需的 JavaScript 會隨著面載入而自動地加入頁面之中(打開瀏覽器執行畫面的原始檔即可看見)。


圖 17 Atlas TextBox 自動完成控制項執行畫面

(五)範例五 以 Data-binding 與樣板建立 Atlas 網頁應用程式

本範例是利用 Atlas 伺服端的控制項 Listview 控制項繫結到資料來源,並將結果顯示在 Listview 控制項的樣板之中。此外這個範例共沒有使用到 Master Page,因為前面曾經說過 Master Page 對 Atlas Frameowrk 技術並非是必要的,只不過借用 Master Page 的優點不必每個 Page 都必須撰寫 Atlas Script 參照,讓程式版面比較清爽;並且由於少了 Master Page 所帶來的佈景主題外觀樣式,故在程式裡面改用了 site.css 檔案來定義外觀,以下為步驟說明:

Step 1:建立 Atlas 伺服器控制項
以下為 Lab5.aspx 程式碼:

<%@ Page Language="C#" %>

<!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 id="Head1" runat="server">
    <title>Atlas Server Controls Lab</title>
    <link rel="stylesheet" type="text/css" href="site.css" />
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <atlas:ScriptManager id="mgr1" runat="server" />
    
    <atlas:button runat="server" id="fillButton" text="Get URL List">
      <click>
        <actions>
          <atlas:invokeMethodAction target="dataSource1" method="select" />
        </actions>
      </click>
    </atlas:button>
    
    <atlas:dataSource runat="server" id="dataSource1" serviceUrl="~/DataService.asmx" />
    
    <atlas:ListView runat="server" id="listView1" itemtemplatecontrolid="templateItem">
    
      <bindings>
        <atlas:Binding DataContext="dataSource1" DataPath="data" Property="data" />
      </bindings>
      
      <LayoutTemplate>
        <ul runat="server" id="templateItemParent">
          <li runat="server" id="templateItem">
            <strong id="Strong1" runat="server">
                <atlas:label runat="server" id="nameLabel">
                  <bindings>
                    <atlas:binding DataPath="Name" Property="text" />
                  </bindings>
                </atlas:label>
            </strong>
            <br />
            <atlas:hyperlink runat="server" id="companyUrl" >
              <bindings>
                <atlas:binding DataPath="Description" Property="text" />
              </bindings>           
            </atlas:hyperlink>
          </li>
        </ul>
      </LayoutTemplate>
      
      <emptytemplate>No Data</emptytemplate>
    </atlas:ListView>
    
  </div>
  </form>
</body>
</html> 

程式說明:
以上 ListView 控制項、資料繫結方式與樣板宣告語法,與 ASP.NET 2.0 控制項宣告的方式非常接近或者說概念相同;而只要是 Server 端的 Atlas 控制項都必須引入 ScriptManager 來做 Script 管理,它是用來管理和加入 Atlas 伺服端所必須的 JavaScript。

Step 2:使用 DataService.asmx 網路服務
DataService.asmx 並不須要額外建立,因為 Hands-On 專案樣板已包括了這支程式,本程是回傳欲繫結的資料,以下為程式碼:

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

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Web;
using System.Web.Caching;
using System.Web.Services;
using System.Web.Services.Protocols;
using Microsoft.Web.Services;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class SampleDataService : DataService {
	static List<SampleRow> _data;
	static int _nextId;
	static object _dataLock = new object();

	private static List<SampleRow> Data 
    {
		get 
        {
			if (_data == null) 
            {
				lock (_dataLock) 
                {
					if (_data == null) 
                    {
						_data = new List<SampleRow>();
						_data.Add(new SampleRow(0, "A. Datum Corporation", 
"http://www.adatum.com")); _data.Add(new SampleRow(1, "Adventure Works",
"http://www.adventure-works.com")); _data.Add(new SampleRow(2, "Alpine Ski House",
"http://www.alpineskihouse.com")); _data.Add(new SampleRow(3, "Baldwin Museum of Science",
"http://www.baldwinmuseumofscience.com")); _data.Add(new SampleRow(4, "Blue Yonder Airlines",
"http://www.blueyonderairlines.com")); _data.Add(new SampleRow(5, "City Power & Light",
"http://www.cpandl.com")); _data.Add(new SampleRow(6, "Coho Vineyard",
"http://www.cohovineyard.com")); _data.Add(new SampleRow(7, "Contoso, Ltd",
"http://www.contoso.com")); _data.Add(new SampleRow(8, "Graphic Design Institute",
"http://www.graphicdesigninstitute.com")); _nextId = 9; } } } return _data; } } [DataObjectMethod(DataObjectMethodType.Delete)] public void DeleteRow(int id) { foreach (SampleRow row in _data) { if (row.Id == id) { lock (_dataLock) { _data.Remove(row); } break; } } } [DataObjectMethod(DataObjectMethodType.Select)] public SampleRow[] SelectRows() { return SampleDataService.Data.ToArray(); } [DataObjectMethod(DataObjectMethodType.Insert)] public SampleRow InsertRow(string organization, string url) { SampleRow newRow; lock (_dataLock) { newRow = new SampleRow(_nextId++, organization, url); _data.Add(newRow); } return newRow; } [DataObjectMethod(DataObjectMethodType.Update)] public void UpdateRow(SampleRow updateRow) { foreach (SampleRow row in _data) { if (row.Id == updateRow.Id) { row.Name =updateRow.Name; row.Description = updateRow.Description; break; } } } }

程式說明:
同樣地,若看不懂上面 DataService.asmx 程式並不重要,只要知道它是將資料回傳給 Atlas ListView 控制項做繫結用途就可以了。


圖 18 Atlas ListView 控制項執行畫面

Web.config 組態檔

使用 Atlas Hands-On-Lab VSI 様板時,您可能不見得會注意到在專案角落中有一個隱形人,它就是 Web.config 組態檔,與一般的專案組態檔不同它裡面加入了 Atlas 運作所必須的相關設定,以下是其組態設定:

<?xml version="1.0"?>
<!-- 
    Note: As an alternative to hand editing this file you can use the 
    web admin tool to configure settings for your application. Use
    the Website->Asp.Net Configuration option in Visual Studio.
    A full list of settings and comments can be found in 
    machine.config.comments usually located in 
    \Windows\Microsoft.Net\Framework\v2.x\Config 
-->
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
    <!-- 
        The configSections define a section for ASP.NET Atlas
    -->
    <configSections>
        <sectionGroup name="microsoft.web" type="Microsoft.Web.Configuration.MicrosoftWebSectionGroup">
            <section name="scripts" type="Microsoft.Web.Configuration.ScriptsSection"/>
            <section name="converters" type="Microsoft.Web.Configuration.ConvertersSection"/>
        </sectionGroup>
    </configSections>

    <!-- 
        atlas.web section defines the script files required for the Atlas framework when used in 
        the client
    -->
    <microsoft.web>
        <scripts scriptLibraryPath="~/ScriptLibrary/">
        </scripts>
        <converters>
            <add type="Microsoft.Web.Services.Converters.DateTimeConverter"/>
            <add type="Microsoft.Web.Services.Converters.DataSetConverter"/>
            <add type="Microsoft.Web.Services.Converters.DataRowConverter"/>
            <add type="Microsoft.Web.Services.Converters.DataTableConverter"/>
        </converters>
    </microsoft.web>
    <appSettings/>
    <connectionStrings/>
    <system.web>
      <pages>
          <controls>
              <add namespace="Microsoft.Web" assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/>
              <add namespace="Microsoft.Web.Components" assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/>
              <add namespace="Microsoft.Web.UI" assembly="Microsoft.Web.Atlas" tagPrefix="atlas"/>
          </controls>
      </pages>
       <!-- 
            Set compilation debug="true" to insert debugging 
            symbols into the compiled page. Because this 
            affects performance, set this value to true only 
            during development.
        -->
        <compilation debug="false">
          <buildProviders>
              <add extension=".script" type="Microsoft.Web.Compilation.ScriptBuildProvider" />
          </buildProviders>
        </compilation>

        <!--
            ASMX is mapped to a new handler so that proxy JavaScripts can also be served
         -->
        <httpHandlers>
            <remove verb="*" path="*.asmx"/>
            <add verb="*" path="*.asmx" type="Microsoft.Web.Services.ScriptHandlerFactory" validate="false"/>
        </httpHandlers>
        <httpModules>
            <add name="ScriptModule" type="Microsoft.Web.Services.ScriptModule"/>
        </httpModules>
        <!--
            The <authentication> section enables configuration 
            of the security authentication mode used by 
            ASP.NET to identify an incoming user. 
        -->
        <authentication mode="Windows"/>
        <!--
            The <customErrors> section enables configuration 
            of what to do if/when an unhandled error occurs 
            during the execution of a request. Specifically, 
            it enables developers to configure html error pages 
            to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm"/>
            <error statusCode="404" redirect="FileNotFound.htm"/>
        </customErrors>
        -->
    </system.web>
</configuration>

檢視 Atlas Framework 技術藍圖的承諾

透過上面五個範例可以察知 Atlas Framework 運作包含了幾個重要部分:

  1. 傳統 JavaScript
  2. 改良 JavaScript 後的 Atlas Script Library(Atlas Script Framework)
  3. Atlas UI Control(Client 端)
  4. Atlas 伺服器控制項(Server 端)
  5. Web.config 組態檔

由以上幾個範例所包含的技術來檢視當初 Atlas Framework 藍圖是否相符?

以下是 Atlas Framework 藍圖當初所設定的目標,以下是簡要分析:

(一) 在 Client 端方面

  • 物件導向開發
    Atlas 所使用的 JavaScript 已是被改良具備物件導向能力,檢視結果相符。
  • 瀏覽器相容性
    各位從 Lab1 中可以看到程式中參照不同瀏覽器平台的 JavaScript,不需要程式開發人員為同一個網頁應用程式撰寫數種不同瀏覽器平台程式版本,可省卻程式設計師不少力氣,檢視結果相符。
  • 行為與 Client 端元件
    從 Lab3 就可以看到 Atlas 提供了 Client 端元件供開發人員使用,並且裡面是大家所熟悉的行為屬性宣告,檢視結果相符。
  • 負責處理遠端呼叫的程式碼
    透過簡單的 Web Service 參照宣告即可讓程式進行非同步網路服務呼叫,完全不需要使用者花費額外力氣處理相關的技術細節,檢視結果相符。
  • 宣告式程式撰寫模式
    從 Lab2 就可以看見宣告 Atlas 程式如同您在宣告一般 ASP.NET 程式一樣容易,而非自成一格的奇怪宣告模式,有助於程式設計師能夠以現有 ASP.NET 宣告語法進行 Atlas 程式開發,檢視結果相符。


圖 19 Atlas Client 端組成元件架構圖

(二) 在 Server 端方面

  • Web 伺服器控制項
    不像有些 AJAX Library 比較偏向用 Client 端技術來解決 AJAX 程式開發,單單只有 Client 端的解決方案在許多時候將會顯得非常不足,因此微軟除了 Client 端之外,在 Server 端亦展現出其優越的開發技術,各位可以回想 ASP.NET 1.0 憑藉著豐富的伺服器控制項、Postback 與 CodeBehind 技術獲得非常大的成功,因此微軟亦打算採用此一成功策略,擬在伺服端展現 Atlas 控制項的強大能力,讓程式開發人員很簡單就可以搞定複雜的功能,如 Lab4 只需要二行伺服器宣告就能夠達到「自動完成」的功能,令人感到驚豔,檢視結果相符。
  • Web 服務
    從上面五個範例都是使用 Web 服務的情況下,各位可以知道 Web 服務對 Atlas 有多麼的重要,透過 Web 服務可以將 Client 端與 Server 端緊緊結合在一起,並且 Web 服務能夠將 Server 端的力量源源不絕地輸送給 Client 端,如此可達成 Rich Client 目的,大大地增加網頁程式的豐富性與靈活度,因此可以巨幅縮減與傳統 WinForm 應用程式的落差,檢視結果相符。


圖 20 Atlas 伺服端元件架構圖

由以上的分析可以知道,當初微軟對 Atlas Framework 藍圖所做的承諾,在每個構面檢視中幾乎都確實相符,同時亦非常努力地實踐出當初藍圖規劃的目標,就目前筆者研究 Atlas 所得到的資訊,Atlas Framework 開發小組企圖心不止於此,因為他們似乎很認真看待 AJAX 這塊技術,而非只想隨隨便便推出一個 AJAX 套件應付了事,仍然非常邁力地推進它到另一個頂峰!為何這點很重要?因為技術藍圖規劃的完整性、功能強大性、實踐的程度可供我們判斷其是否值得投資,因為在眾多的技術中可以察知它是否屬於最佳人選,或只是聊備一格的功能,倘若將來開發更為複雜的 AJAX 應用程式還必須用其他產品來輔助,如此就失去了使用它的意義,因為我們不希望看到一個 AJAX 應用程式專案是由許多 AJAX Framework 所組成的雜牌軍,如此只會造成學習、開發與維護的龐大負擔,因此就目前看來 Atlas Framework 是很優的技術,值得您信賴與投資,至少在 ASP.NET 2.0 平台上它將會是標準、是王者,同時 ASP.NET 2.0 也比 ASP.NET 1.0 多了一道賣點,也許用過其他 AJAX Library 的朋友很可能會這樣想:「我在 ASP.NET 1.0 照樣可以達成非同步的功能」,的確是沒錯!但是 Atlas Framework 終將與它們不一樣,有什麼地方不一樣?簡單來說 Atlas 將會變成跟喝白開水一樣容易,只要會寫 ASP.NET 就會寫 Atlas 非同步技術,不需要額外苦修勤練就能得道成仙,而不是像使用其他 AJAX 技術還得挑燈夜戰苦練大成,並且能夠與 ASP.NET 2.0 新功能與機制完全結合,高下立判!

結論

Atlas Framework 確實能夠有效簡化 AJAX 開發的複雜度,同時能夠滿足非同步系統的開發需求,但有些技術區塊目前仍無緣看到,以及完整的說明文件也非常不足,這是由於 Atlas Framework 目前連 Beta1 都還算不上,只是預覽版而已,即便如此仍不能阻擋廣大程式設計師想獲得 Atlas 力量的熱切期望,一如神劍現蹤勢必成為各路英雄好漢爭奪的寶物,而 Atlas 的力量就只有如此嗎?答案是還不止,下期將為您揭露得道成仙的重要祕密心訣,讓您足踏 Atlas 這把利劍御風直上青雲,筆者將為您揭開這不可思議的重大變革,Atlas 不只是 Atlas,遠比你想像中的還要容易、更為強大,我們下期見。

posted on 2007-09-03 14:28  steventong  阅读(809)  评论(0编辑  收藏  举报

页脚Html代码