.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:N141215503
出刊日期:2014/12/31
開發工具:Visual Studio 2013 Ultimate Update 3
版本:.NET Framework 4.5.x
相信有許多網站都想要設計類似Google網站首頁的搜尋功能,只要在Google首頁的文字方塊中,輸入一些查詢關鍵字,文字方塊底下,馬上幫你在背後偷偷下一個查詢,從遠端伺服器,下載符合查詢條件的提示字串,自動地顯示下文字方塊下方,供使用者做選擇,我們稱之為自動完成功能,請參考下圖所示:

圖 1:Google首頁。
要設計類似這樣功能的網頁有許多套件可以使用,jQuery Foundation推出的jQuery UI就是其中頗受歡迎的套件之一,它是一個以jQuery函式庫為基礎的外掛(plug-ins),非常簡單、容易使用,就可以設計出具高互動性的網站應用程式,並可以搭配多種網站開發程式使用,像是微軟的ASPN.ET。
jQuery UI包含一個Autocomplete Widget可以設計出類似Google首頁這樣的效果。不過,若要設計一個這樣的網頁,除了需要jQuery UI套件之外,你還需要撰寫一個伺服端的程式碼,每當使用者在網頁文字方塊輸入關鍵字時,偷偷在用戶端利用jQuery下查詢,叫用伺服端的程式,將滿足篩選條件的資料回傳,再透過jQuery UI,將資料動態呈現在文字方塊下方。
要設計伺服器端的程式有許多的選項可供選擇,因此,在此系列的文章中,我將介紹如何分別使用Web Form、ASP.NET Web Service(ASMX)、WCF服務,以及ASP.NET Web API、MVC Action Method等技術,來整合jQuery UI Autocomplete Widget實作自動完成功能。
使用Web Form設計伺服端程式
我們先從使用Web Form(附檔名為aspx的檔案)當做伺服端程式開始說起。接下來的步驟將使用Visual Studio 2013的Web Site的方式來建立網站。啟動Visual Studio 2013開發環境,從 Visual Studio 2013的主選單點選「File」-「New」-「Web Site」選項,接著會開啟「New Web Site」對話窗。在右邊的Templates區塊中選擇「ASP.NET Empty Web Site」,請參考下圖所示:

圖 2:Google首頁。
從Visual Studio 2013的「WEBSITE」選單,選取「Add New Item」項目,新增一個ASP.NET Web Form (ASPX)網頁,請參考下圖所示:

圖 3:新增一個ASP.NET Web Form 網頁(ASPX)。
在「Add New Item」對話盒中,選取「Web Form」,設定名稱「GetData.aspx」,然後按下「Add」按鈕,新增一個網頁,請參考下圖所示:

圖 4:新增一個ASPX網頁。
雙擊「Design」設計畫面空白處,進入程式設計視窗,Visual Studio 會自動產生一個Page_Load方法,刪除所有的HTML標籤,在其中加入以下程式碼:
<%@ Page Language = "C#" %>
<script runat = "server">
protected void Page_Load( object sender , EventArgs e ) {
Response.ContentType = "application/json";
var term = Request.Params[ "term" ];
string[ ] data = { "Microsoft" , "apple" , "Linux" , "Cisco" , "Oracle" , "Sun" , "Misc" };
var results = ( from d in data where d.ToUpper( ).StartsWith( term.ToUpper( ) ) select d ).ToList( );
System.Web.Script.Serialization.JavaScriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer( );
Response.Write( ser.Serialize( results ) );
}
</script>
由於當下最流行的是以JSON做為交換資料的格式,範例中利用Response物件將ContentType 設定為「application/json」表示要送回JSON格式資料,然後將符合查詢條件的資料(即文字字串是以某個字母開頭的),利用JavaScriptSerializer 物件序列化成JSON格式回傳。
從「Solution Explorer」視窗,選取「Default.aspx」,按滑鼠右鍵,從快捷選單中選取「View In Browser」選項,執行網頁,以查詢字串輸入查詢關鍵字,將m開頭的所有字串回傳:
http://localhost:38547/GetData.aspx?term=m
執行結果參考如下:

圖 5:回傳「m」開頭字串。
下圖是將「s」開頭的所有字串回傳之執行結果:

圖 6:回傳「s」開頭字串。。
下載「jQuery」2.0.3版函式庫
用戶端的程式需要使用到jQuery與jQuery UI函式庫,在Visual Studio 2013開發工具中,可以使用Nuget套件管理員下載它們。在「Solution Explorer」視窗選取專案名稱。從Visual Studio 2013開發工具「TOOLS」-「Library Package Manager」-「Package Manage Console」開啟「Package Manage Console」視窗,然後在提示字元中輸入install-package指令,並使用「-version」指定安裝jQuery 2.0.3版本:
Install-Package jQuery -Version 2.0.3
得到的執行結果如下圖所示:

圖 7:下載「jQuery」2.0.3版函式庫。
下載「jQuery UI (Combined Library)」1.11.1版函式庫
下一步,使用Nuget套件管理員下載「jQuery UI (Combined Library)」1.11.1版函式庫。在「Solution Explorer」視窗選取專案名稱。從Visual Studio 2013開發工具「TOOLS」-「Library Package Manager」-「Package Manage Console」開啟「Package Manage Console」視窗,然後在提示字元中輸入install-package指令,並使用「-version」指定安裝jQuery UI (Combined Library) 1.11.1版本:
Install-Package jQuery.UI.Combined -Version 1.11.1
得到的執行結果如下圖所示:

圖 8:下載「jQuery UI (Combined Library)」1.11.1版函式庫。
使用GET方法回傳JSON格式資料
用戶端的程式可以是Web Form(ASPX)網頁或HTML。我們就以HTML為例子。在Visual Studio 2013「WEBSITE」-「Add New Item」對話盒中,選取「HTML Page」,設定名稱,然後按下「Add」按鈕,新增一個網頁,網頁程式碼參考如下:
<!DOCTYPE html>
<html xmlns = "
http://www.w3.org/1999/xhtml">
<head>
<title> </title>
<link href = "Content/themes/base/all.css" rel = "stylesheet" />
</head>
<body>
<input type="text" name="myInput" id="myInput" />
<script src="Scripts/jquery-2.0.3.js"></script>
<script src="Scripts/jquery-ui-1.11.1.js"></script>
<script>
$( function () {
$( "#myInput" ).autocomplete( {
source: function ( request, callback ) {
var data = { term: request.term };
$.ajax( {
url: "GetData.aspx",
type: "GET",
data: data,
async: false,
complete: function ( xhr, result ) {
var lists = JSON.parse( xhr.responseText );
callback( lists );
}
} );
}
} )
} );
</script>
</body>
</html>
網頁的設計重點如下:
- 在<head>標籤之中,加入以下引用jQuery UI 樣式表語法。
- 在<body>的<div>標籤之中加入一個HTML - input標籤。
- 在</body>標籤之上引用jQuery以及jQuery UI函式庫。
- 加入<script>區塊,於jQuery的ready事件撰寫程式碼,叫用ajax方法取回資料,使用HTTP GET方法呼叫ASPX檔案,將執行結果指定給jQuery UI Autocomplete Widget的source屬性。在source的callback函式中,可以利用request.term取得文字方塊中,使用者輸入的關鍵字。
現在可以來測試網頁的執行結果了。從「Solution Explorer」視窗- 選取Views\Home資料夾下的HTML網頁,按CTRL+F5執行網頁,執行結果參考如下:

圖 9:自動完成功能。
使用POST方法回傳JSON格式資料
除了使用HTTP Get方法之外,你也可以很容易地改用HTTP POST方法來叫用Web Form取回資料,只要將上例的程式碼,叫用ajax方法時,將「type」設定為「POST」就可以得到相同的效果,程式碼參考如下:
<!DOCTYPE html>
<html xmlns="
http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link href="Content/themes/base/all.css" rel="stylesheet" />
</head>
<body>
<input type="text" name="myInput" id="myInput" />
<script src="Scripts/jquery-2.0.3.js"></script>
<script src="Scripts/jquery-ui-1.11.1.js"></script>
<script>
$( function () {
$( "#myInput" ).autocomplete( {
source: function ( request, callback ) {
var data = { term: request.term };
$.ajax( {
url: "GetData.aspx",
type: "POST",
data: data,
async: false,
complete: function ( xhr, result ) {
var lists = JSON.parse( xhr.responseText );
callback( lists );
}
} );
}
} )
} );
</script>
</body>
</html>
ASP.NET Web Service(ASMX)
接著,讓我們使用ASP.NET Web Service(ASMX)當做伺服端程式。延續前面的專案,加入一個ASP.NET Web Service(ASMX)。從Visual Studio 2013開發工具-「Solution Explorer」視窗- 專案名稱上方按滑鼠右鍵,從快捷選單選擇「Add」- 「Add New Item」,開啟「Add New Item」對話盒,從右上方文字方塊輸入「web service」搜尋,選取「Web Service (ASMX)」,設定名稱為「WebService.asmx」,清除勾選右下方的「Place code in separate file」,然後按下「Add」按鈕,建立新服務,請參考下圖所示:

圖 10:加入ASP.NET Web Service(ASMX)。
修改工具產生的程式碼,將類別上方 [System.Web.Script.Services.ScriptService] 這行程式的註解拿掉,以開放透過ASP.NET AJAX方式叫用,再撰寫一個GetData方法,上方標示「WebMethod」Attribute,開放外部程式做呼叫,GetData方法會根據傳入的term關鍵字,篩選回傳符合條件的資料(以某個字開頭的字串):
<%@ WebService Language="C#" Class="WebService" %>
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Linq;
[WebService(Namespace = "
http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService {
[WebMethod]
public string[ ] GetData( string term ) {
string[ ] data = { "Microsoft" , "apple" , "Linux" , "Cisco" , "Oracle" , "Sun" , "Misc" };
var result = ( from d in data where d.ToUpper( ).StartsWith( term.ToUpper( ) ) select d ).ToArray( );
return result;
}
}
你不需要在程式中指定要回傳JSON或XML格式的資料,Web Service會自動根據需求決定。測試一下服務是否能正常執行。從「Solution Explorer」視窗- 選取CustomerInfo.asmx檔案,按CTRL+F5執行,執行結果參考如下,你將看到一個Web服務測試頁面,點選瀏覽器上的「GetData」超連結:

圖 11:Web服務測試頁面。
進入Web服務測試畫面,輸入term為「m」,按下「Invoke」按鈕,請參考下圖所示:

圖 12:叫用服務。
得到的執行結果如下圖所示,資料預設以XML方式回傳:

圖 13:取回XML格式資料。
使用POST方法回傳 JSON格式資料
若想要Web服務(ASMX)回傳 JSON格式資料,需要以POST方式呼叫服務,並設定contentType為「"application/json; charset=utf-8"」,term參數要序列化成為json格式傳遞,程式參考如下:
<!DOCTYPE html>
<html xmlns="
http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link href="Content/themes/base/all.css" rel="stylesheet" />
</head>
<body>
<input type="text" name="myInput" id="myInput" />
<script src="Scripts/jquery-2.0.3.min.js"></script>
<script src="Scripts/jquery-ui-1.11.1.js"></script>
<script>
$( function () {
$( "#myInput" ).autocomplete( {
source: function ( request, callback ) {
var data = { term: request.term };
$.ajax( {
type: "POST",
contentType: "application/json; charset=utf-8",
url: "WebService.asmx/GetData",
dataType: "json",
data: JSON.stringify( data ), //必需要序列化為json
async: false,
success: function ( data ) {
console.log( data );
callback( data.d );
}
} );
}
} )
} );
</script>
</body>
</html>
使用POST方法回傳 XML格式資料
若想要Web服務(ASMX)回傳 XML格式資料,則不用設定contentType,資料也不需序列化為JSON格式,取回XML格式的資料之後,再透過jQuery解析XML文件內容,程式參考如下:
<!DOCTYPE html>
<html xmlns="
http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link href="Content/themes/base/all.css" rel="stylesheet" />
</head>
<body>
<input type="text" name="myInput" id="myInput" />
<script src="Scripts/jquery-2.0.3.min.js"></script>
<script src="Scripts/jquery-ui-1.11.1.js"></script>
<script>
$( function () {
$( "#myInput" ).autocomplete( {
source: function ( request, callback ) {
var data = { term: request.term };
$.ajax( {
url: "WebService.asmx/GetData",
type: "POST",
data: data,
async: false,
success: function ( xml ) {
console.log( xml );
var lists = [];
$( xml ).find( "string" ).each( function () {
lists.push( $( this ).text() );
} );
callback( lists );
}
} );
}
} )
} );
</script>
</body>
</html>
使用GET方法回傳 XML格式資料
預設為了安全性考量,Web服務並不允許使用HTTP GET方式呼叫,若需要使用GET方式叫用服務,則需要在網站根目錄下的Web.config檔案之中,加入以下設定,以啟用HttpGET:
<configuration>
<system.web>
<webServices>
<protocols>
<add name="HttpSoap"/>
<add name="HttpPost"/>
<add name="HttpGet"/>
</protocols>
</webServices>
<compilation debug="true" targetFramework="4.5.1" />
<httpRuntime targetFramework="4.5.1" />
</system.web>
</configuration>
接著就可以在網頁之中使用HTTP GET來叫用服務:
<!DOCTYPE html>
<html xmlns="
http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link href="Content/themes/base/all.css" rel="stylesheet" />
</head>
<body>
<input type="text" name="myInput" id="myInput" />
<script src="Scripts/jquery-2.0.3.min.js"></script>
<script src="Scripts/jquery-ui-1.11.1.js"></script>
<script>
$( function () {
$( "#myInput" ).autocomplete( {
source: function ( request, callback ) {
var data = { term: request.term };
$.ajax( {
url: "WebService.asmx/GetData",
type: "get",
data: data,
async: false,
success: function ( xml ) {
console.log( xml );
var lists = [];
$( xml ).find( "string" ).each( function () {
lists.push( $( this ).text() );
} );
callback( lists );
}
} );
}
} );
} );
</script>
</body>
</html>
小結
在下一篇文章中我們將探討如何叫用WCF服務,以及如何利用Web API,和MVC的Action Method來回傳符合篩選條件的資料。