在以下部分中,添加了按流派或名稱(chēng)搜索電影。
將以下突出顯示的屬性添加到 Pages/Movies/Index.cshtml.cs:
C#
public class IndexModel : PageModel
{
private readonly RazorPagesMovie.Models.RazorPagesMovieContext _context;
public IndexModel(RazorPagesMovie.Models.RazorPagesMovieContext context)
{
_context = context;
}
public IList<Movie> Movie { get; set; }
[BindProperty(SupportsGet = true)]
public string SearchString { get; set; }
// Requires using Microsoft.AspNetCore.Mvc.Rendering;
public SelectList Genres { get; set; }
[BindProperty(SupportsGet = true)]
public string MovieGenre { get; set; }
警告
出于安全原因,必須選擇綁定 GET 請(qǐng)求數(shù)據(jù)以對(duì)模型屬性進(jìn)行分頁(yè)。 請(qǐng)?jiān)趯⒂脩?hù)輸入映射到屬性前對(duì)其進(jìn)行驗(yàn)證。 當(dāng)處理依賴(lài)查詢(xún)字符串或路由值的方案時(shí),選擇加入 GET 綁定非常有用。
要將屬性綁定在 GET 請(qǐng)求上,請(qǐng)將 [BindProperty] 特性的 SupportsGet 屬性設(shè)置為 true: [BindProperty(SupportsGet = true)]
使用以下代碼更新索引頁(yè)面的 OnGetAsync 方法:
C#
public async Task OnGetAsync()
{
var movies = from m in _context.Movie
select m;
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Movie = await movies.ToListAsync();
}
OnGetAsync 方法的第一行創(chuàng)建了 LINQ 查詢(xún)用于選擇電影:
C#
// using System.Linq;
var movies = from m in _context.Movie
select m;
此時(shí)僅對(duì)查詢(xún)進(jìn)行了定義,它還不會(huì)針對(duì)數(shù)據(jù)庫(kù)運(yùn)行。
如果 SearchString 屬性不為 null 或空,則電影查詢(xún)會(huì)修改為根據(jù)搜索字符串進(jìn)行篩選:
C#
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
s => s.Title.Contains() 代碼是 Lambda 表達(dá)式。 Lambda 在基于方法的 LINQ 查詢(xún)中用作標(biāo)準(zhǔn)查詢(xún)運(yùn)算符方法的參數(shù),如 Where 方法或 Contains(前面的代碼中所使用的)。 在對(duì) LINQ 查詢(xún)進(jìn)行定義或通過(guò)調(diào)用方法(如 Where、Contains 或 OrderBy)進(jìn)行修改后,此查詢(xún)不會(huì)被執(zhí)行。 相反,會(huì)延遲執(zhí)行查詢(xún)。 這意味著表達(dá)式的計(jì)算會(huì)延遲,直到循環(huán)訪問(wèn)其實(shí)現(xiàn)的值或者調(diào)用 ToListAsync 方法為止。 有關(guān)詳細(xì)信息,請(qǐng)參閱 Query Execution(查詢(xún)執(zhí)行)。
注意:Contains 方法在數(shù)據(jù)庫(kù)中運(yùn)行,而不是在 C# 代碼中運(yùn)行。 查詢(xún)是否區(qū)分大小寫(xiě)取決于數(shù)據(jù)庫(kù)和排序規(guī)則。 在 SQL Server 上,Contains 映射到 SQL LIKE,這是不區(qū)分大小寫(xiě)的。 在 SQLite 中,由于使用了默認(rèn)排序規(guī)則,因此需要區(qū)分大小寫(xiě)。
導(dǎo)航到電影頁(yè)面,并向 URL追加一個(gè)如 ?searchString=Ghost 的查詢(xún)字符串(例如 https://localhost:5001/Movies?searchString=Ghost)。 篩選的電影將顯示出來(lái)。
如果向索引頁(yè)面添加了以下路由模板,搜索字符串則可作為 URL 段傳遞(例如 https://localhost:5001/Movies/Ghost)。
CSHTML
@page "{searchString?}"
前面的路由約束允許按路由數(shù)據(jù)(URL 段)搜索標(biāo)題,而不是按查詢(xún)字符串值進(jìn)行搜索。"{searchString?}" 中的 ? 表示這是可選路由參數(shù)。
ASP.NET Core 運(yùn)行時(shí)使用模型綁定,通過(guò)查詢(xún)字符串 (?searchString=Ghost) 或路由數(shù)據(jù) (https://localhost:5001/Movies/Ghost) 設(shè)置 SearchString 屬性的值。 模型綁定搜索不區(qū)分大小寫(xiě)。
但是,不能指望用戶(hù)修改 URL 來(lái)搜索電影。 在此步驟中,會(huì)添加 UI 來(lái)篩選電影。 如果已添加路由約束 "{searchString?}",請(qǐng)將它刪除。
打開(kāi) Pages/Movies/Index.cshtml 文件,并添加以下代碼中突出顯示的 <form> 標(biāo)記:
CSHTML
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-page="Create">Create New</a>
</p>
<form>
<p>
Title: <input type="text" asp-for="SearchString" />
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
@*Markup removed for brevity.*@
HTML <form> 標(biāo)記使用以下標(biāo)記幫助程序:
保存更改并測(cè)試篩選器。
使用以下代碼更新 OnGetAsync 方法:
C#
public async Task OnGetAsync()
{
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
var movies = from m in _context.Movie
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);
}
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Movie = await movies.ToListAsync();
}
下面的代碼是一種 LINQ 查詢(xún),可從數(shù)據(jù)庫(kù)中檢索所有流派。
C#
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
流派的 SelectList 是通過(guò)投影截然不同的流派創(chuàng)建的。
C#
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
更新 Index.cshtml,如下所示:
CSHTML
@page
@model RazorPagesMovie.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-page="Create">Create New</a>
</p>
<form>
<p>
<select asp-for="MovieGenre" asp-items="Model.Genres">
<option value="">All</option>
</select>
Title: <input type="text" asp-for="SearchString" />
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
@*Markup removed for brevity.*@
通過(guò)按流派或/和電影標(biāo)題搜索來(lái)測(cè)試應(yīng)用。
更多建議: