搜尋
注意
本教學課程的更新版本 可在這裡 使用最新版本的 Visual Studio。 新的教學課程會使用ASP.NET Core MVC,這可針對本教學課程提供許多改善。
本教學課程可讓您了解 ASP.NET Core MVC 與控制器和檢視。 Razor Pages 是 ASP.NET Core 的新替代方案,這是頁面型程式設計模型,可讓建置 Web UI 變得更簡單且更具生產力。 建議您在嘗試使用 MVC 版本之前,先試試 Razor 頁面教學課程。 Razor 頁面教學課程:
- 比較容易學習。
- 涵蓋更多功能。
- 這是新應用程式開發的慣用方法。
新增搜尋方法和搜尋檢視
在本節中,您會將搜尋功能新增至 Index
動作方法,讓您依內容類型或名稱搜尋電影。
必要條件
若要符合本節的螢幕擷取畫面,您必須執行應用程式 (F5) ,並將下列電影新增至資料庫。
標題 | 發行日期 | Genre | 價格 |
---|---|---|---|
Ghostbusters | 6/8/1984 | 喜劇 | 6.99 |
Ghostbusters II | 6/16/1989 | 喜劇 | 6.99 |
Apes 的行星 | 3/27/1986 | 動作 | 5.99 |
更新索引表單
首先,將 Index
動作方法更新至現有的 MoviesController
類別。 此程式碼如下:
public ActionResult Index(string searchString)
{
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}
方法的第一行 Index
會建立下列 LINQ 查詢來選取電影:
var movies = from m in db.Movies
select m;
此時會定義查詢,但尚未針對資料庫執行。
searchString
如果參數包含字串,則會修改電影查詢,以使用下列程式碼篩選搜尋字串的值:
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
上述 s => s.Title
程式碼是 Lambda 運算式。 Lambda 用於以方法為基礎的 LINQ 查詢,作為標準查詢運算子方法的引數,例如上述程式碼中使用的 Where 方法。 LINQ 查詢在定義時,或藉由呼叫 或 OrderBy
等 Where
方法來修改 LINQ 查詢時,不會執行查詢。 相反地,查詢執行會延遲,這表示運算式的評估會延遲,直到實際逐一查看其實現值或 ToList
呼叫 方法為止。 在範例中 Search
,查詢會在 Index.cshtml 檢視中執行。 如需延後查詢執行的詳細資訊,請參閱查詢執行。
注意
Contains方法是在資料庫上執行,而不是上述 c# 程式碼。 在資料庫上, Contains 會 對應至不區分大小寫的 SQL LIKE。
現在您可以更新 Index
顯示表單給使用者的檢視。
執行應用程式並流覽至 /Movies/Index。 將查詢字串 (例如 ?searchString=ghost
) 附加至 URL。 隨即顯示篩選過的電影。
如果您將 方法的 Index
簽章變更為具有名為 id
的參數,參數 id
將會符合 {id}
App_Start\RouteConfig.cs 檔案中所設定之預設路由的預留位置。
{controller}/{action}/{id}
原始 Index
方法看起來像這樣::
public ActionResult Index(string searchString)
{
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}
修改 Index
過的方法如下所示:
public ActionResult Index(string id)
{
string searchString = id;
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}
您現在可以將搜尋標題作為路由資料 (URL 區段) 傳遞,而不是作為查詢字串值。
但是,您不能期望使用者在每次想要搜尋電影時修改 URL。 因此,現在您將新增可協助他們篩選電影的 UI。 如果您變更方法的 Index
簽章以測試如何傳遞路由系結識別碼參數,請將它變更回 ,讓您的 Index
方法採用名為 的 searchString
字串參數:
public ActionResult Index(string searchString)
{
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
return View(movies);
}
開啟 Views\Movies\Index.cshtml 檔案,然後在 之後 @Html.ActionLink("Create New", "Create")
,新增以下醒目提示的表單標記:
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
@using (Html.BeginForm()){
<p> Title: @Html.TextBox("SearchString") <br />
<input type="submit" value="Filter" /></p>
}
</p>
協助 Html.BeginForm
程式會建立開頭 <form>
標記。 協助 Html.BeginForm
程式會在使用者按一下 [ 篩選 ] 按鈕來提交表單時,讓表單自行張貼。
Visual Studio 2013在顯示和編輯檢視檔案時有良好的改善。 當您執行開啟檢視檔案的應用程式時,Visual Studio 2013叫用正確的控制器動作方法來顯示檢視。
在 Visual Studio 中開啟 [索引] 檢視 (,如上圖所示) ,點選 Ctr F5 或 F5 以執行應用程式,然後嘗試搜尋電影。
方法沒有 HttpPost
多載 Index
。 您不需要它,因為方法不會變更應用程式的狀態,只是篩選資料。
您可以新增下列 HttpPost Index
方法。 在此情況下,動作叫用程式會符合 HttpPost Index
方法,而且 方法 HttpPost Index
會執行,如下圖所示。
[HttpPost]
public string Index(FormCollection fc, string searchString)
{
return "<h3> From [HttpPost]Index: " + searchString + "</h3>";
}
不過,即使您新增這個 HttpPost
版本的 Index
方法,在如何全部實作此方法方面仍然有其限制。 假設您想要將特定的搜尋加為書籤,或者想要傳送連結給朋友,讓他們可以點選來查看相同的電影篩選清單。 請注意,HTTP POST 要求的 URL 與 GET 要求的 URL 相同, (localhost:xxxxx/Movies/Index) -- URL 本身沒有搜尋資訊。 現在,搜尋字串資訊會以表單欄位值的形式傳送至伺服器。 這表示您無法擷取搜尋資訊,將搜尋資訊加入書簽或傳送給 URL 中的朋友。
解決方案是使用 的多載 BeginForm
,指定 POST 要求應該將搜尋資訊新增至 URL,而且應該路由至 HttpGet
方法的版本 Index
。 以下列標記取代現有的無 BeginForm
參數方法:
@using (Html.BeginForm("Index","Movies",FormMethod.Get))
現在當您提交搜尋時,URL 會包含搜尋查詢字串。 即使您有 HttpPost Index
方法,搜尋也會移至 HttpGet Index
動作方法。
依內容類型新增搜尋
如果您已新增 HttpPost
方法的版本 Index
,請立即將其刪除。
接下來,您將新增功能,讓使用者依內容類型搜尋電影。 以下列程式碼取代 Index
方法:
public ActionResult Index(string movieGenre, string searchString)
{
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
return View(movies);
}
這個版本的 Index
方法會採用其他參數,也就是 movieGenre
。 前幾行程式碼會建立 List
物件,以保存資料庫中的電影內容類型。
下列程式碼是一種 LINQ 查詢,其會從資料庫中擷取所有的內容類型。
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
程式碼會 AddRange
使用泛型 List
集合的 方法,將所有不同的內容類型新增至清單。 (如果沒有 Distinct
修飾詞,則會新增重複的內容類型,例如,在我們的範例中會新增兩次 comedy) 。 然後,程式碼會將內容類型清單儲存在 物件中 ViewBag.MovieGenre
。 將類別資料儲存 (這類電影內容類型) 為 中的 ViewBag
SelectList物件,然後在下拉式清單方塊中存取類別資料是 MVC 應用程式的一般方法。
下列程式碼示範如何檢查 movieGenre
參數。 如果不是空的,程式碼會進一步限制電影查詢,以將選取的電影限制為指定的內容類型。
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
如先前所述,在動作方法傳回) 之後 Index
,影片清單會逐一查看檢視中發生的 (,否則不會在資料庫上執行查詢。
將標記新增至索引檢視,以支援依內容類型搜尋
Html.DropDownList
在協助程式之前 TextBox
,將協助程式新增至Views\Movies\Index.cshtml檔案。 完成的標記如下所示:
@model IEnumerable<MvcMovie.Models.Movie>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
@using (Html.BeginForm("Index", "Movies", FormMethod.Get))
{
<p>
Genre: @Html.DropDownList("movieGenre", "All")
Title: @Html.TextBox("SearchString")
<input type="submit" value="Filter" />
</p>
}
</p>
<table class="table">
在下列程式碼中:
@Html.DropDownList("movieGenre", "All")
參數 「MovieGenre」 提供協助程式在 中尋找 IEnumerable<SelectListItem>
的 ViewBag
索引鍵 DropDownList
。 ViewBag
已在動作方法中填入 :
public ActionResult Index(string movieGenre, string searchString)
{
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
return View(movies);
}
參數 「All」 提供選項標籤。 如果您在瀏覽器中檢查該選擇,您會看到其「值」屬性是空的。 由於我們的控制器只會篩選 if
字串不是 null
或空白,因此提交空白值以顯示 movieGenre
所有內容類型。
您也可以預設設定要選取的選項。 如果您想要 「Comedy」 作為預設選項,您會變更控制器中的程式碼,如下所示:
ViewBag.movieGenre = new SelectList(GenreLst, "Comedy");
執行應用程式並流覽至 /Movies/Index。 依內容類型、電影名稱及兩個準則嘗試搜尋。
在本節中,您已建立搜尋動作方法和檢視,讓使用者依電影標題和內容類型搜尋。 在下一節中,您將瞭解如何將屬性新增至 Movie
模型,以及如何新增將會自動建立測試資料庫的初始化運算式。
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應