在以下部分中,添加了按流派或名稱搜索電影。
將以下突出顯示的屬性添加到 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 請求數(shù)據(jù)以對模型屬性進行分頁。 請在將用戶輸入映射到屬性前對其進行驗證。 當處理依賴查詢字符串或路由值的方案時,選擇加入 GET 綁定非常有用。
要將屬性綁定在 GET 請求上,請將 [BindProperty] 特性的 SupportsGet 屬性設置為 true: [BindProperty(SupportsGet = true)]
使用以下代碼更新索引頁面的 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 查詢用于選擇電影:
C#
// using System.Linq;
var movies = from m in _context.Movie
select m;
此時僅對查詢進行了定義,它還不會針對數(shù)據(jù)庫運行。
如果 SearchString 屬性不為 null 或空,則電影查詢會修改為根據(jù)搜索字符串進行篩選:
C#
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
s => s.Title.Contains() 代碼是 Lambda 表達式。 Lambda 在基于方法的 LINQ 查詢中用作標準查詢運算符方法的參數(shù),如 Where 方法或 Contains(前面的代碼中所使用的)。 在對 LINQ 查詢進行定義或通過調用方法(如 Where、Contains 或 OrderBy)進行修改后,此查詢不會被執(zhí)行。 相反,會延遲執(zhí)行查詢。 這意味著表達式的計算會延遲,直到循環(huán)訪問其實現(xiàn)的值或者調用 ToListAsync 方法為止。 有關詳細信息,請參閱 Query Execution(查詢執(zhí)行)。
注意:Contains 方法在數(shù)據(jù)庫中運行,而不是在 C# 代碼中運行。 查詢是否區(qū)分大小寫取決于數(shù)據(jù)庫和排序規(guī)則。 在 SQL Server 上,Contains 映射到 SQL LIKE,這是不區(qū)分大小寫的。 在 SQLite 中,由于使用了默認排序規(guī)則,因此需要區(qū)分大小寫。
導航到電影頁面,并向 URL追加一個如 ?searchString=Ghost 的查詢字符串(例如 https://localhost:5001/Movies?searchString=Ghost)。 篩選的電影將顯示出來。
如果向索引頁面添加了以下路由模板,搜索字符串則可作為 URL 段傳遞(例如 https://localhost:5001/Movies/Ghost)。
CSHTML
@page "{searchString?}"
前面的路由約束允許按路由數(shù)據(jù)(URL 段)搜索標題,而不是按查詢字符串值進行搜索。"{searchString?}" 中的 ? 表示這是可選路由參數(shù)。
ASP.NET Core 運行時使用模型綁定,通過查詢字符串 (?searchString=Ghost) 或路由數(shù)據(jù) (https://localhost:5001/Movies/Ghost) 設置 SearchString 屬性的值。 模型綁定搜索不區(qū)分大小寫。
但是,不能指望用戶修改 URL 來搜索電影。 在此步驟中,會添加 UI 來篩選電影。 如果已添加路由約束 "{searchString?}",請將它刪除。
打開 Pages/Movies/Index.cshtml 文件,并添加以下代碼中突出顯示的 <form> 標記:
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> 標記使用以下標記幫助程序:
保存更改并測試篩選器。
使用以下代碼更新 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 查詢,可從數(shù)據(jù)庫中檢索所有流派。
C#
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
流派的 SelectList 是通過投影截然不同的流派創(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.*@
通過按流派或/和電影標題搜索來測試應用。
更多建議: