共用方式為


ASP.NET Web Pages簡介 - HTML 表單基本概念

作者:Tom FitzMacken

本教學課程說明如何建立輸入表單的基本概念,以及如何在使用 ASP.NET Web Pages (Razor) 時處理使用者的輸入。 現在您已擁有資料庫,您將使用表單技能讓使用者在資料庫中尋找特定電影。 假設您已透過使用 ASP.NET Web Pages顯示資料的簡介來完成系列。

您將學到什麼:

  • 如何使用標準 HTML 元素建立表單。
  • 如何讀取表單中的使用者輸入。
  • 如何使用使用者提供的搜尋字詞,建立選擇性地取得資料的 SQL 查詢。
  • 如何讓頁面中的欄位「記住」使用者輸入的內容。

討論的功能/技術:

  • Request 物件。
  • SQL Where 子句。

您要建置的內容

在上一個教學課程中,您已建立資料庫、新增資料,然後使用 WebGrid 協助程式來顯示資料。 在本教學課程中,您將新增搜尋方塊,讓您尋找特定內容類型的電影,或其標題包含您輸入的任何單字。 例如, (,您可以找到所有內容類型為「動作」或標題包含 「設定」或「Adventure」的電影。)

當您完成本教學課程時,您將會有如下的頁面:

具有內容類型和標題搜尋的電影頁面

頁面的清單部分與上一個教學課程中的相同, 方格。 差異在於方格只會顯示您搜尋的電影。

關於 HTML 表單

(如果您曾體驗過建立 HTML 表單,以及 與 POST 之間的差異 GET ,您可以略過本節。)

表單具有使用者輸入元素 — 文字方塊、按鈕、選項按鈕、核取方塊、下拉式清單等等。 使用者填寫這些控制項或進行選取,然後按一下按鈕以提交表單。

此範例說明表單的基本 HTML 語法:

<form method="post">
  <input type="text" name="name" value="" />
  <br/>
  <input type="submit" name="submit" value="Submit" />
</form>

當此標記在頁面中執行時,它會建立類似下圖的簡單表單:

在瀏覽器中呈現的基本 HTML 表單

元素 <form> 會封入要提交的 HTML 專案。 (簡單的錯誤是將元素新增至頁面,但忘記將它們放在元素內 <form> 。在此情況下,不會提交任何專案。) 屬性 method 會告知瀏覽器如何提交使用者輸入。 如果您要在伺服器上執行更新,或 get 只是從伺服器擷取資料,請將此 post 設定為 。

提示

GET、POST 和 HTTP 動詞安全性

HTTP 是瀏覽器和伺服器用來交換資訊的通訊協定,在其基本作業中相當簡單。 瀏覽器只會使用幾個動詞對伺服器提出要求。 當您撰寫 Web 的程式碼時,瞭解這些動詞以及瀏覽器和伺服器如何使用它們會很有説明。 最常用動詞和最遠的動詞是:

  • GET. 瀏覽器會使用此動詞從伺服器擷取專案。 例如,當您在瀏覽器中輸入 URL 時,瀏覽器會 GET 執行作業來要求您想要的頁面。 如果頁面包含圖形,瀏覽器會執行其他 GET 作業來取得影像。 GET如果作業必須傳遞資訊至伺服器,則會在查詢字串中傳遞資訊做為 URL 的一部分。
  • POST. 瀏覽器會傳送 POST 要求,以提交伺服器上要新增或變更的資料。 例如, POST 動詞命令是用來在資料庫中建立記錄,或變更現有的記錄。 大部分時候,當您填寫表單並按一下 [提交] 按鈕時,瀏覽器會 POST 執行作業。 POST在作業中,要傳遞至伺服器的資料位於頁面主體中。

這些動詞之間的重要區別在於 GET ,作業不應該變更伺服器上的任何專案,或以稍微抽象的方式 GET 放置作業,作業不會產生伺服器上的狀態變更。 您可以視需要對相同資源執行 GET 作業多次,而且這些資源不會變更。 (作業 GET 通常稱為「安全」,或使用技術詞彙是 等冪。) 當然, POST 每次執行作業時,要求都會變更伺服器上的某個專案。

兩個範例將協助說明這項區別。 當您使用 Bing 或 Google 之類的引擎執行搜尋時,您會填入包含一個文字方塊的表單,然後按一下搜尋按鈕。 瀏覽器會 GET 執行作業,並將您輸入的值傳入做為 URL 一部分的方塊中。 GET針對這種類型的表單使用作業很正常,因為搜尋作業不會變更伺服器上的任何資源,所以只會擷取資訊。

現在,請考慮線上訂購專案的程式。 您填寫訂單詳細資料,然後按一下 [提交] 按鈕。 這項作業將會是要求 POST ,因為作業會導致伺服器上的變更,例如新的訂單記錄、帳戶資訊的變更,以及許多其他變更。 不同于此 GET 作業,您無法重複您的 POST 要求, 如果您在每次重新提交要求時,就會在伺服器上產生新的訂單。 (在這種情況下,網站通常會警告您不要多次按一下提交按鈕,或停用提交按鈕,以免意外重新提交表單。)

在本教學課程的課程中,您將使用 GET 作業和 POST 作業來處理 HTML 表單。 我們會在每個案例中說明為何您使用的動詞是適當的動詞。

(若要深入瞭解 HTTP 動詞命令,請參閱 W3C site.) 上的 方法定義 一文

大部分的使用者輸入元素都是 HTML <input> 元素。 其看起來像 <input type="type" name="name">,類型 指出您想要的使用者輸入控制項類型。 這些元素是常見的元素:

  • 文字方塊: <input type="text">
  • 核取方塊: <input type="check">
  • 選項按鈕: <input type="radio">
  • 按鈕: <input type="button">
  • 提交按鈕: <input type="submit">

您也可以使用 <textarea> 元素來建立多行文字方塊,以及 <select> 建立下拉式清單或可捲動清單的 元素。 (如需 HTML 表單元素的詳細資訊,請參閱 W3Schools 網站上的 HTML 表單和輸入 。)

屬性 name 非常重要,因為名稱是稍後取得元素值的方式,因為您很快就會看到。

有趣的部分是您頁面開發人員對使用者的輸入所做的作業。 沒有與這些專案相關聯的內建行為。 相反地,您必須取得使用者輸入或選取的值,並使用它們執行某些動作。 這就是您將在本教學課程中學到的內容。

提示

HTML5 和輸入表單

如您所知,HTML 正在轉換,而最新版本 (HTML5) 包含使用者輸入資訊的更直覺方式支援。 例如,在 HTML5 中, (頁面開發人員) 可以告訴頁面您想要使用者輸入日期。 瀏覽器接著可以自動顯示行事曆,而不需要使用者手動輸入日期。 不過,HTML5 是新的,而且尚未在所有瀏覽器中受到支援。

ASP.NET Web Pages支援 HTML5 輸入到使用者瀏覽器的程度。 如需 HTML5 中元素的新屬性 <input> 概念,請參閱 W3Schools 網站上的 HTML < 輸入 > 類型 Attribute

建立表單

在 WebMatrix 的 [ 檔案] 工作區中,開啟 Movies.cshtml 頁面。

在結尾 </h1> 標記和呼叫的 grid.GetHtml 開頭 <div> 標記之前,新增下列標記:

<form method="get">
  <div>
    <label for="searchGenre">Genre to look for:</label>
    <input type="text" name="searchGenre" value="" />
    <input type="Submit" value="Search Genre" /><br/>
    (Leave blank to list all movies.)<br/>
    </div>
</form>

此標記會建立一個表單,其中包含名為 的 searchGenre 文字方塊和提交按鈕。 文字方塊和提交按鈕會包含在 屬性設定為 get 的專案 method<form> 。 (請記住,如果您未將文字方塊和提交按鈕放在元素內 <form> ,當您按一下按鈕時不會提交任何內容。) 您在這裡使用 GET 動詞,因為您正在建立的表單不會在伺服器上進行任何變更,它只會產生搜尋結果。 (在上一個教學課程中,您使用了方法 post ,也就是您提交變更至伺服器的方式。您會在下一個教學課程中再次看到。)

執行頁面。 雖然您尚未定義表單的任何行為,但您可以看到它的外觀:

具有內容類型搜尋方塊的電影頁面

在文字方塊中輸入值,例如 「Comedy」。然後按一下 [搜尋內容類型]。

記下頁面的 URL。 因為您將元素的 method 屬性設定 <form>get ,所以您輸入的值現在是 URL 中查詢字串的一部分,如下所示:

http://localhost:45661/Movies.cshtml?searchGenre=Comedy

讀取表單值

頁面已經包含一些程式碼,可取得資料庫資料,並在方格中顯示結果。 現在您必須新增一些程式碼來讀取文字方塊的值,以便執行包含搜尋字詞的 SQL 查詢。

由於您將表單的 方法設定為 get ,因此您可以使用如下所示的程式碼,讀取在文字方塊中輸入的值:

var searchTerm = Request.QueryString["searchGenre"];

物件 Request.QueryString (QueryString 物件屬性 Request) 包含已提交為作業一 GET 部分的專案值。 屬性 Request.QueryString 包含 集合 (表單中提交之值的清單) 。 若要取得任何個別值,您可以指定您想要的專案名稱。 這就是為什麼您必須在 name 建立文字方塊 (<input>) searchTerm 元素上擁有 屬性。 (如需物件的詳細資訊 Request ,請參閱 稍後的提要欄 。)

它夠簡單,足以讀取文字方塊的值。 但是,如果使用者未在文字方塊中輸入任何專案,但仍然按一下 [ 搜尋 ],您可以忽略該點選,因為沒有任何專案可以搜尋。

下列程式碼是示範如何實作這些條件的範例。 (您還不需要新增此程式碼;您會在一段時間執行此動作。)

if(!Request.QueryString["searchGenre"].IsEmpty() ) {
     // Do something here
}

測試會以這種方式細分:

  • 取得 的值,也就是在名為 searchGenre 的專案 Request.QueryString["searchGenre"]<input> 輸入的值。
  • 使用 方法找出其是否空白 IsEmpty 。 此方法是判斷某個專案 (的標準方式,例如,表單專案) 是否包含值。 但實際上,您只會在意它 不是 空的,因此...
  • ! 測試前面 IsEmpty 新增 運算子。 ! (運算子表示邏輯 NOT) 。

在純英文中,整個 if 條件會轉譯成下列內容: 如果表單的 searchGenre 元素不是空的,則 ...

此區塊會設定建立使用搜尋字詞之查詢的階段。 您將在下一節中執行該動作。

提示

Request 物件

物件 Request 包含瀏覽器在要求或提交頁面時傳送至應用程式的所有資訊。 此物件包含使用者提供的任何資訊,例如文字方塊值或要上傳的檔案。 它也包含各種其他資訊,例如 Cookie、URL 查詢字串中的值, (如果有任何) 、正在執行的網頁檔案路徑、使用者所使用的瀏覽器類型、在瀏覽器中設定的語言清單等等。

物件 Request 是值的 集合 (清單) 。 您可以藉由指定其名稱,從集合中取得個別值:

var someValue = Request["name"];

物件 Request 實際上會公開數個子集。 例如:

  • Request.Form如果要求是 POST 要求,則提供來自提交 <form> 專案內之元素的值。
  • Request.QueryString 只提供 URL 查詢字串中的值。 (在類似 http://mysite/myapp/page?searchGenre=action&page=2 的 URL 中, ?searchGenre=action&page=2 URL 的區段是查詢字串。)
  • Request.Cookies 集合可讓您存取瀏覽器已傳送的 Cookie。

若要取得您知道的值是在提交的表單中,您可以使用 Request["name"] 。 或者,您可以針對 POST 要求使用更特定的版本 Request.Form["name"] () ,或 Request.QueryString["name"] 針對要求使用) (GET 。 當然, name 是要取得的專案名稱。

您想要取得的專案名稱必須在您使用的集合中是唯一的。 這就是物件提供 和 等 Request.FormRequest.QueryString 子集的原因 Request 。 假設您的頁面包含名為 userName 的表單專案, 包含名為 的 userName Cookie。 如果您收到 Request["userName"] ,則不論您想要表單值或 Cookie,它都模棱兩可。 不過,如果您取得 Request.Form["userName"]Request.Cookie["userName"] ,則會明確說明要取得的值。

最好是特定,並使用您感興趣的子集 Request ,例如 Request.FormRequest.QueryString 。 針對您在本教學課程中建立的簡單頁面,可能不會真的有任何差異。 不過,當您建立更複雜的頁面時,使用明確的版本 Request.FormRequest.QueryString 可協助您避免當頁面包含表單 (或多個表單) 、Cookie、查詢字串值等時可能發生的問題。

使用搜尋字詞建立查詢

既然您已瞭解如何取得使用者輸入的搜尋字詞,您可以建立使用該字詞的查詢。 請記住,若要從資料庫中取得所有電影專案,您會使用類似下列語句的 SQL 查詢:

SELECT * FROM Movies

若要只取得特定電影,您必須使用包含 子句的 Where 查詢。 這個子句可讓您設定查詢傳回資料列的條件。 以下為範例:

SELECT * FROM Movies WHERE Genre = 'Action'

基本格式為 WHERE column = value 。 除了 之外 = ,您可以使用不同的運算子,例如 > (大於) 、 < (小於) 、 (不等於) 、 <><= (小於或等於) 等,依您尋找的內容而定。

如果您想知道,SQL 語句不區分大小寫— SELECT 與 (或甚至 select) 相同 Select 。 不過,人們通常會將 SQL 語句中的關鍵字大寫,例如 SELECTWHERE ,以便更容易閱讀。

將搜尋字詞當作參數傳遞

搜尋特定內容類型很簡單, WHERE Genre = 'Action' () ,但您想要能夠搜尋使用者輸入的任何內容類型。 若要這樣做,您要建立為 SQL 查詢,其中包含要搜尋之值的預留位置。 此命令看起來會像這樣:

SELECT * FROM Movies WHERE Genre = @0

預留位置是 @ 後面接著零的字元。 如您所猜測,查詢可以包含多個預留位置,且其名稱 @0 為 、 @1@2 等。

若要設定查詢並實際傳遞該值,請使用如下所示的程式碼:

selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
selectedData = db.Query(selectCommand, Request.QueryString["searchGenre"]);

此程式碼類似于您已完成的作業,以在方格中顯示資料。 唯一的差異是:

  • 此查詢包含預留位置 (WHERE Genre = @0") 。
  • 查詢會放入變數 (selectCommand) ;之前,您直接將查詢傳遞至 db.Query 方法。
  • 當您呼叫 db.Query 方法時,會同時傳遞查詢和要用於預留位置的值。 (如果查詢有多個預留位置,您會將它們全部當作個別值傳遞至 method.)

如果您將所有元素放在一起,您會取得下列程式碼:

if(!Request.QueryString["searchGenre"].IsEmpty() ) { 
    searchTerm = Request.QueryString["searchGenre"];
    selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
    selectedData = db.Query(selectCommand, searchTerm);
}

注意

重要! 使用預留位置 (,例如 @0) 將值傳遞至 SQL 命令對於安全性而言 非常重要 。 您在這裡看到的方法是使用變數資料的預留位置,是您應該建構 SQL 命令的唯一方式。

永遠不要將 (串連) 常值文字和您從使用者取得的值,來建構 SQL 語句。 將使用者輸入串連至 SQL 語句會將您的網站開啟至 SQL 插入式攻擊 ,其中惡意使用者將值提交至您的頁面,以入侵您的資料庫。 (您可以在 MSDN 網站 SQL 插入 一文中深入瞭解。)

使用搜尋程式碼更新影片頁面

現在,您可以在 Movies.cshtml 檔案中更新程式碼。 若要開始,請將頁面頂端程式碼區塊中的程式碼取代為下列程式碼:

var db = Database.Open("WebPagesMovies");
var selectCommand = "SELECT * FROM Movies";
var searchTerm = "";

此處的差異在於,您已將查詢放入變數中 selectCommand ,稍後會傳遞至 db.Query 該變數。 將 SQL 語句放入變數可讓您變更 語句,這是您將執行的搜尋動作。

您也移除了這兩行,稍後會放回:

var selectedData = db.Query("SELECT * FROM Movies");
var grid = new WebGrid(source: selectedData, rowsPerPage: 3);

您不想執行查詢 (亦即呼叫 db.Query) ,而且您還不想初始化 WebGrid 協助程式。 在找出哪些 SQL 語句必須執行之後,您將會執行這些動作。

在此重寫區塊之後,您可以新增處理搜尋的新邏輯。 完成的程式碼看起來會像下面這樣。 更新頁面中的程式碼,使其符合此範例:

@{
    var db = Database.Open("WebPagesMovies") ;
    var selectCommand = "SELECT * FROM Movies";
    var searchTerm = "";

    if(!Request.QueryString["searchGenre"].IsEmpty() ) {
        selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
        searchTerm = Request.QueryString["searchGenre"];
    }

    var selectedData = db.Query(selectCommand, searchTerm);
    var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3);
}

頁面現在的運作方式如下。 每次執行頁面時,程式碼都會開啟資料庫,並將 selectCommand 變數設定為 SQL 語句,以取得 Movies 資料表中的所有記錄。 程式碼也會初始化 searchTerm 變數。

不過,如果目前的要求包含 元素的值 searchGenre ,程式碼會將 設定 selectCommand 為不同的查詢,也就是包含 Where 要搜尋內容類型之 子句的查詢。 它也會設定 searchTerm 為搜尋方塊所傳遞的任何專案, (可能沒有任何) 。

不論哪一個 SQL 語句位於 selectCommand 中,程式碼接著會呼叫 db.Query 來執行查詢,並傳遞任何在 中的任何專案 searchTerm 。 如果 中 searchTerm 沒有任何專案,則並不重要,因為在此情況下,沒有參數可傳遞值 selectCommand

最後,程式碼會使用查詢結果來初始化 WebGrid 協助程式,就像之前一樣。

您可以藉由將 SQL 語句和搜尋字詞放入變數中,來將彈性新增至程式碼。 如您稍後在本教學課程中所見,您可以使用此基本架構,並持續新增不同類型的搜尋邏輯。

測試依內容類型搜尋功能

在 WebMatrix 中,執行 Movies.cshtml 頁面。 您會看到包含內容類型文字方塊的頁面。

輸入您針對其中一個測試記錄輸入的內容類型,然後按一下 [ 搜尋]。 這次您只會看到符合該內容類型的電影清單:

搜尋內容類型 'Comedies' 之後的電影頁面清單

輸入不同的內容類型,然後再次搜尋。 嘗試使用所有小寫或全部大寫字母來輸入內容類型,讓您可以看到搜尋不區分大小寫。

「記住」使用者輸入的內容

您可能已經注意到,在您輸入內容類型並按一下 [ 搜尋內容類型] 之後,您會看到該內容類型的清單。 不過,搜尋文字方塊是空的,換句話說,它不會記住您輸入的內容。

請務必瞭解發生此行為的原因。 當您提交頁面時,瀏覽器會將要求傳送至網頁伺服器。 當 ASP.NET 取得要求時,它會建立頁面的全新實例、在頁面中執行程式碼,然後再次將頁面轉譯至瀏覽器。 不過,實際上,頁面不知道您只是使用舊版本身。 它知道它收到一個要求,其中包含一些表單資料。

每次您要求頁面時,無論是第一次還是提交頁面,您都會收到新的頁面。 網頁伺服器沒有上次要求的記憶體。 兩者都 ASP.NET,而且瀏覽器都不會。 頁面這些個別實例之間的唯一連線是您在頁面之間傳輸的任何資料。 例如,如果您提交頁面,新的頁面實例可以取得先前實例所傳送的表單資料。 (另一種在頁面之間傳遞資料的方式是使用 cookies.)

描述這種情況的正式方式,就是說網頁是 無狀態的。 網頁伺服器和頁面本身和頁面中的元素不會維護有關頁面先前狀態的任何資訊。 Web 的設計方式是這樣,因為維護個別要求的狀態會快速耗盡網頁伺服器的資源,這通常處理數千個甚至數百萬個每秒的要求。

這就是為什麼文字方塊是空的。 提交頁面之後,ASP.NET 建立頁面的新實例,並執行程式碼和標記。 該程式碼中沒有任何內容會告知 ASP.NET 將值放入文字方塊中。 因此,ASP.NET 未執行任何動作,而且文字方塊的轉譯沒有值。

實際上有一個簡單的方法可以解決此問題。 您在文字方塊中輸入的內容類型 可供 您在程式碼中使用,其位於 Request.QueryString["searchGenre"] 中。

更新文字方塊的標記, value 讓屬性從 searchTerm 取得其值,如下列範例所示:

<input type="text" name="searchGenre" value="@Request.QueryString["searchGenre"]" />

在此頁面中,您也可以將 屬性設定 valuesearchTerm 變數,因為該變數也包含您輸入的內容類型。 但是, Request 使用 物件來設定 value 屬性,如下所示是完成這項工作的標準方式。 (假設您甚至想要這樣做, 在某些情況下,您可能會想要轉譯頁面, 而不需要 欄位中的值。這全都取決於 app.)

注意

您無法「記住」用於密碼的文字方塊值。 這是一個安全性漏洞,可讓使用者使用程式碼填入密碼欄位。

再次執行頁面,輸入內容類型,然後按一下 [搜尋內容類型]。 這次不只會看到搜尋的結果,但文字方塊會記住您上次輸入的內容:

顯示文字方塊已「記住」上一個專案的頁面

在標題中搜尋任何Word

您現在可以搜尋任何內容類型,但您可能也想要搜尋標題。 當您搜尋時,很難完全正確取得標題,因此您可以改為搜尋標題內任何位置出現的單字。 若要在 SQL 中執行此動作,請使用 LIKE 運算子和語法,如下所示:

SELECT * FROM Movies WHERE Title LIKE '%adventure%'

此命令會取得其標題包含 「adventure」 的所有電影。 當您使用 運算子時 LIKE ,您會在搜尋字詞中包含萬用字元 %LIKE 'adventure%'搜尋表示「從 'adventure'開始」。 (技術上,這表示「字串 'adventure' 後面接著任何專案」。) 同樣地,搜尋字詞 LIKE '%adventure' 表示「任何後面接著字串 'adventure'」,這是另一種說出「以 'adventure' 結尾」的方式。

因此搜尋字詞 LIKE '%adventure%' 表示「標題中的任何位置都有 'adventure'」。 (技術上「標題中的任何專案,後面接著 「adventure',後面接著任何專案」。)

<form> 元素內,在結尾元素) 之前,于內容類型搜尋的結尾 </div></form> 標籤底下新增下列標記 (:

<div>
  <label for="SearchTitle">Movie title contains the following:</label>
  <input type="text" name="searchTitle" value="@Request.QueryString["searchTitle"]" />
  <input type="Submit" value="Search Title" /><br/>
</div>

處理此搜尋的程式碼類似于內容類型搜尋的程式碼,但您必須組合 LIKE 搜尋。 在頁面頂端的程式碼區塊內,在內容類型搜尋的區塊後面 if 新增此 if 區塊:

if(!Request.QueryString["searchTitle"].IsEmpty() ) {
    selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
    searchTerm = "%" + Request["searchTitle"] + "%";
}

此程式碼會使用您稍早看到的相同邏輯,不同之處在于搜尋會使用 LIKE 運算子,而程式碼會在搜尋字詞前後放置 「 % 」。

請注意,將另一個搜尋新增至頁面很容易。 您只需要:

  • 建立已 if 測試的區塊,以查看相關的搜尋方塊是否有值。
  • selectCommand 變數設定為新的 SQL 語句。
  • searchTerm 變數設定為要傳遞至查詢的值。

以下是完整的程式碼區塊,其中包含標題搜尋的新邏輯:

@{
    var db = Database.Open("WebPagesMovies") ;
    var selectCommand = "SELECT * FROM Movies";
    var searchTerm = "";

    if(!Request.QueryString["searchGenre"].IsEmpty() ) {
        selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
        searchTerm = Request.QueryString["searchGenre"];
    }

   if(!Request.QueryString["searchTitle"].IsEmpty() ) {
        selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
        searchTerm = "%" + Request["searchTitle"] + "%";
    }

    var selectedData = db.Query(selectCommand, searchTerm);
    var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:8);
}

以下是此程式碼的功能摘要:

  • 變數 searchTermselectCommand 會在頂端初始化。 您會根據使用者在頁面中所做的動作,將這些變數設定為適當的搜尋字詞, (是否有任何) 和適當的 SQL 命令。 預設搜尋是從資料庫取得所有電影的簡單案例。
  • 在 和 searchGenresearchTitle 的測試中,程式碼會將 設定 searchTerm 為您要搜尋的值。 這些程式碼區塊也會針對該搜尋設定 selectCommand 為適當的 SQL 命令。
  • 方法 db.Query 只會叫用一次,使用中 selectedCommand 任何 SQL 命令,以及 中任何值。 searchTerm 如果沒有搜尋字詞 (沒有內容類型,而且沒有標題字詞) ,則 的值 searchTerm 是空字串。 不過,這並不重要,因為在此情況下,查詢不需要參數。

測試標題搜尋功能

現在您可以測試已完成的搜尋頁面。 執行 Movies.cshtml

輸入內容類型,然後按一下 [搜尋內容類型]。 方格會顯示該內容類型的電影,例如之前。

輸入標題字,然後按一下 [搜尋標題]。 格線會顯示標題中有該單字的電影。

在標題中搜尋 'The' 之後的電影頁面清單

將這兩個文字方塊保留空白,然後按一下任一按鈕。 方格會顯示所有電影。

合併查詢

您可能會注意到您可以執行的搜尋是獨佔的。 即使這兩個搜尋方塊都有值,您也無法同時搜尋標題和內容類型。 例如,您無法搜尋標題包含 「Adventure」 的所有動作電影。 (當您輸入內容類型和標題的值時,如果輸入內容類型和標題的值,則標題搜尋會優先。) 若要建立結合條件的搜尋,您必須建立語法如下的 SQL 查詢:

SELECT * FROM Movies WHERE Genre = @0 AND Title LIKE @1

而且您必須使用類似下列語句的語句來執行查詢 (大致上說出) :

var selectedData = db.Query(selectCommand, searchGenre, searchTitle);

建立邏輯以允許許多搜尋準則排列,可以像您所見一樣參與一些。 因此,我們將在此停止。

即將推出下一個

在下一個教學課程中,您將建立一個頁面,該頁面會使用表單讓使用者將電影新增至資料庫。

@{
    var db = Database.Open("WebPagesMovies") ;
    var selectCommand = "SELECT * FROM Movies";
    var searchTerm = "";

    if(!Request.QueryString["searchGenre"].IsEmpty() ) {
        selectCommand = "SELECT * FROM Movies WHERE Genre = @0";
        searchTerm = Request.QueryString["searchGenre"];
    }

    if(!Request.QueryString["searchTitle"].IsEmpty() ) {
        selectCommand = "SELECT * FROM Movies WHERE Title LIKE @0";
        searchTerm = "%" + Request["searchTitle"] + "%";
    }

    var selectedData = db.Query(selectCommand, searchTerm);
    var grid = new WebGrid(source: selectedData, defaultSort: "Genre", rowsPerPage:3);
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Movies</title>
    <style type="text/css">
      .grid { margin: 4px; border-collapse: collapse; width: 600px; }
      .grid th, .grid td { border: 1px solid #C0C0C0; padding: 5px; }
      .head { background-color: #E8E8E8; font-weight: bold; color: #FFF; }
      .alt { background-color: #E8E8E8; color: #000; }
    </style>
  </head>
  <body>
    <h1>Movies</h1>
      <form method="get">
        <div>
        <label for="searchGenre">Genre to look for:</label>
        <input type="text" name="searchGenre" value="@Request.QueryString["searchGenre"]" />
        <input type="Submit" value="Search Genre" /><br/>
        (Leave blank to list all movies.)<br/>
        </div>

        <div>
          <label for="SearchTitle">Movie title contains the following:</label>
          <input type="text" name="searchTitle" value="@Request.QueryString["searchTitle"]" />
          <input type="Submit" value="Search Title" /><br/>
        </div>
      </form>

    <div>
      @grid.GetHtml(
        tableStyle: "grid",
        headerStyle: "head",
        alternatingRowStyle: "alt",
        columns: grid.Columns(
          grid.Column("Title"),
          grid.Column("Genre"),
          grid.Column("Year")
        )
      )
    </div>
  </body>
</html>

其他資源