第 6 部分,將搜尋新增至 ASP.NET Core Razor 頁面

注意

這不是這篇文章的最新版本。 如需目前版本,請參閱本文的 .NET 8 版本

重要

這些發行前產品的相關資訊在產品正式發行前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。

如需目前版本,請參閱本文的 .NET 8 版本

作者:Rick Anderson

在下列各節中,會新增依「內容類型」或「名稱」搜尋電影。

將下列醒目提示的程式碼新增至 Pages/Movies/Index.cshtml.cs

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

    public IList<Movie> Movie { get;set; }  = default!;

    [BindProperty(SupportsGet = true)]
    public string? SearchString { get; set; }

    public SelectList? Genres { get; set; }

    [BindProperty(SupportsGet = true)]
    public string? MovieGenre { get; set; }

在先前的程式碼中:

  • SearchString:包含使用者在搜尋文字方塊中輸入的文字。 SearchString 具有 [BindProperty] 屬性。 [BindProperty] 使用與屬性相同的名稱來繫結表單值和查詢字串。 需要 [BindProperty(SupportsGet = true)] 才能在 HTTP GET 要求上進行繫結。
  • Genres:包含內容類型清單。 Genres 可讓使用者從清單中選取內容類型。 SelectList 需要 using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre:包含使用者所選取的特定內容類型。 例如「西部片」。
  • 稍後在本教學課程中將會使用 GenresMovieGenre

警告

基於安全性考量,您必須選擇將 GET 要求資料繫結到頁面模型屬性。 請先驗證使用者輸入再將其對應至屬性。 在解決仰賴查詢字串或路由值的案例時,選擇使用 GET 繫結會很有幫助。

若要在 GET 要求上繫結屬性,請將 [BindProperty] 屬性的 SupportsGet 屬性設定為 true

[BindProperty(SupportsGet = true)]

如需詳細資訊,請參閱 ASP.NET Core Community Standup: Bind on GET discussion (YouTube)

使用下列程式碼來更新 Index 頁面的 OnGetAsync 方法:

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 方法的第一行會建立 LINQ 查詢,以選取電影:

// using System.Linq;
var movies = from m in _context.Movie
             select m;

這時候,系統只會「定義」查詢,而尚對資料庫執行查詢。

如果 SearchString 屬性不是 null 或空白,則會修改電影查詢來篩選搜尋字串:

if (!string.IsNullOrEmpty(SearchString))
{
    movies = movies.Where(s => s.Title.Contains(SearchString));
}

s => s.Title.Contains() 程式碼是一種 Lambda 運算式。 在以方法為基礎的 LINQ 查詢中,Lambda 會用來作為標準查詢運算子方法的引數,例如 Where 方法或 Contains。 定義 LINQ 查詢或藉由呼叫像是 WhereContainsOrderBy 等方法進行修改時,並不會執行查詢。 而是會延後查詢執行。 運算式的評估會延遲直到該運算式的實現值受到逐一查看,或呼叫 ToListAsync 方法為止。 如需詳細資訊,請參閱查詢執行

注意

Contains 方法是在資料庫上執行,而不是在 C# 程式碼中執行。 查詢的區分大小寫取決於資料庫和定序。 在 SQL Server 上,Contains 對應至 SQL LIKE,因此不區分大小寫。 根據查詢,具有預設定序的 SQLite 是區分大小寫和區分大小寫的組合。 如需不區分大小寫 SQLite 查詢的相關資訊,請參閱下列內容:

流覽至 [電影] 頁面,並將查詢字串附加至 URL,例如 ?searchString=Ghost。 例如: https://localhost:5001/Movies?searchString=Ghost 。 隨即顯示篩選過的電影。

索引檢視

如果您已將下列路由範本新增至 Index 頁面,即可透過 URL 區段的形式來傳遞搜尋字串。 例如: https://localhost:5001/Movies/Ghost

@page "{searchString?}"

上述的路由條件約束可讓您以路由資料的形式 (URL 區段) 搜尋標題,而不是以查詢字串值的形式。 在 ? 中,"{searchString?}" 表示此為選擇性的路由參數。

索引檢視,其中已將 ghost 一詞新增至 URL,而傳回的電影清單包含 Ghostbusters 和 Ghostbusters 2 兩部電影

ASP.NET Core 執行階段使用模型繫結來設定查詢字串 (?searchString=Ghost) 中的 SearchString 屬性值或路由傳送資料 (https://localhost:5001/Movies/Ghost)。 模型繫結是區分大小寫的。

但是,無法預期使用者修改 URL 來搜尋電影。 在此步驟中,會新增用來篩選電影的 UI。 如果您已新增路由條件約束 "{searchString?}",請將它移除。

開啟 Pages/Movies/Index.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> 標籤會使用下列標籤協助程式

儲存變更並測試篩選條件。

已將 ghost 一詞輸入 [標題] 篩選條件文字方塊的 Index 檢視

依內容類型搜尋

以下列程式碼更新 Movies/Index.cshtml.cs 頁面 OnGetAsync 方法:

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 查詢,其會從資料庫中擷取所有的內容類型。

// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
                                orderby m.Genre
                                select m.Genre;

內容類型的 SelectList 是由投影不同的內容類型來建立。

Genres = new SelectList(await genreQuery.Distinct().ToListAsync());

將依內容類型搜尋新增至 Razor 頁面

更新 Index.cshtml<form> 元素,如下列標記中所醒目提示:

@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>

依據內容類型、電影標題和這兩者進行搜尋,藉以測試應用程式。

下一步

在下列各節中,會新增依「內容類型」或「名稱」搜尋電影。

將下列醒目提示的程式碼新增至 Pages/Movies/Index.cshtml.cs

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

    public IList<Movie> Movie { get;set; }  = default!;

    [BindProperty(SupportsGet = true)]
    public string? SearchString { get; set; }

    public SelectList? Genres { get; set; }

    [BindProperty(SupportsGet = true)]
    public string? MovieGenre { get; set; }

在先前的程式碼中:

  • SearchString:包含使用者在搜尋文字方塊中輸入的文字。 SearchString 具有 [BindProperty] 屬性。 [BindProperty] 使用與屬性相同的名稱來繫結表單值和查詢字串。 需要 [BindProperty(SupportsGet = true)] 才能在 HTTP GET 要求上進行繫結。
  • Genres:包含內容類型清單。 Genres 可讓使用者從清單中選取內容類型。 SelectList 需要 using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre:包含使用者所選取的特定內容類型。 例如「西部片」。
  • 稍後在本教學課程中將會使用 GenresMovieGenre

警告

基於安全性考量,您必須選擇將 GET 要求資料繫結到頁面模型屬性。 請先驗證使用者輸入再將其對應至屬性。 在解決仰賴查詢字串或路由值的案例時,選擇使用 GET 繫結會很有幫助。

若要在 GET 要求上繫結屬性,請將 [BindProperty] 屬性的 SupportsGet 屬性設定為 true

[BindProperty(SupportsGet = true)]

如需詳細資訊,請參閱 ASP.NET Core Community Standup: Bind on GET discussion (YouTube)

使用下列程式碼來更新 Index 頁面的 OnGetAsync 方法:

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 方法的第一行會建立 LINQ 查詢,以選取電影:

// using System.Linq;
var movies = from m in _context.Movie
             select m;

這時候,系統只會「定義」查詢,而尚對資料庫執行查詢。

如果 SearchString 屬性不是 null 或空白,則會修改電影查詢來篩選搜尋字串:

if (!string.IsNullOrEmpty(SearchString))
{
    movies = movies.Where(s => s.Title.Contains(SearchString));
}

s => s.Title.Contains() 程式碼是一種 Lambda 運算式。 在以方法為基礎的 LINQ 查詢中,Lambda 會用來作為標準查詢運算子方法的引數,例如 Where 方法或 Contains。 定義 LINQ 查詢或藉由呼叫像是 WhereContainsOrderBy 等方法進行修改時,並不會執行查詢。 而是會延後查詢執行。 運算式的評估會延遲直到該運算式的實現值受到逐一查看,或呼叫 ToListAsync 方法為止。 如需詳細資訊,請參閱查詢執行

注意

Contains 方法是在資料庫上執行,而不是在 C# 程式碼中執行。 查詢的區分大小寫取決於資料庫和定序。 在 SQL Server 上,Contains 對應至 SQL LIKE,因此不區分大小寫。 根據查詢,具有預設定序的 SQLite 是區分大小寫和區分大小寫的組合。 如需不區分大小寫 SQLite 查詢的相關資訊,請參閱下列內容:

流覽至 [電影] 頁面,並將查詢字串附加至 URL,例如 ?searchString=Ghost。 例如: https://localhost:5001/Movies?searchString=Ghost 。 隨即顯示篩選過的電影。

索引檢視

如果您已將下列路由範本新增至 Index 頁面,即可透過 URL 區段的形式來傳遞搜尋字串。 例如: https://localhost:5001/Movies/Ghost

@page "{searchString?}"

上述的路由條件約束可讓您以路由資料的形式 (URL 區段) 搜尋標題,而不是以查詢字串值的形式。 在 ? 中,"{searchString?}" 表示此為選擇性的路由參數。

索引檢視,其中已將 ghost 一詞新增至 URL,而傳回的電影清單包含 Ghostbusters 和 Ghostbusters 2 兩部電影

ASP.NET Core 執行階段使用模型繫結來設定查詢字串 (?searchString=Ghost) 中的 SearchString 屬性值或路由傳送資料 (https://localhost:5001/Movies/Ghost)。 模型繫結是區分大小寫的。

但是,無法預期使用者修改 URL 來搜尋電影。 在此步驟中,會新增用來篩選電影的 UI。 如果您已新增路由條件約束 "{searchString?}",請將它移除。

開啟 Pages/Movies/Index.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> 標籤會使用下列標籤協助程式

儲存變更並測試篩選條件。

已將 ghost 一詞輸入 [標題] 篩選條件文字方塊的 Index 檢視

依內容類型搜尋

使用下列程式碼來更新 Index 頁面的 OnGetAsync 方法:

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 查詢,其會從資料庫中擷取所有的內容類型。

// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
                                orderby m.Genre
                                select m.Genre;

內容類型的 SelectList 是由投影不同的內容類型來建立。

Genres = new SelectList(await genreQuery.Distinct().ToListAsync());

將依內容類型搜尋新增至 Razor 頁面

更新 Index.cshtml<form> 元素,如下列標記中所醒目提示:

@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>

依據內容類型、電影標題和這兩者進行搜尋,藉以測試應用程式。

下一步

在下列各節中,會新增依「內容類型」或「名稱」搜尋電影。

將下列醒目提示的程式碼新增至 Pages/Movies/Index.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{
    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IList<Movie> Movie { get;set; } = default!;
        [BindProperty(SupportsGet = true)]
        public string ? SearchString { get; set; }
        public SelectList ? Genres { get; set; }
        [BindProperty(SupportsGet = true)]
        public string ? MovieGenre { get; set; }

在先前的程式碼中:

  • SearchString:包含使用者在搜尋文字方塊中輸入的文字。 SearchString 具有 [BindProperty] 屬性。 [BindProperty] 使用與屬性相同的名稱來繫結表單值和查詢字串。 需要 [BindProperty(SupportsGet = true)] 才能在 HTTP GET 要求上進行繫結。
  • Genres:包含內容類型清單。 Genres 可讓使用者從清單中選取內容類型。 SelectList 需要 using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre:包含使用者所選取的特定內容類型。 例如「西部片」。
  • 稍後在本教學課程中將會使用 GenresMovieGenre

警告

基於安全性考量,您必須選擇將 GET 要求資料繫結到頁面模型屬性。 請先驗證使用者輸入再將其對應至屬性。 在解決仰賴查詢字串或路由值的案例時,選擇使用 GET 繫結會很有幫助。

若要在 GET 要求上繫結屬性,請將 [BindProperty] 屬性的 SupportsGet 屬性設定為 true

[BindProperty(SupportsGet = true)]

如需詳細資訊,請參閱 ASP.NET Core Community Standup: Bind on GET discussion (YouTube)

使用下列程式碼來更新 Index 頁面的 OnGetAsync 方法:

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 方法的第一行會建立 LINQ 查詢,以選取電影:

// using System.Linq;
var movies = from m in _context.Movie
             select m;

這時候,系統只會「定義」查詢,而尚對資料庫執行查詢。

如果 SearchString 屬性不是 Null 或空白,則會修改電影查詢來篩選搜尋字串:

if (!string.IsNullOrEmpty(SearchString))
{
    movies = movies.Where(s => s.Title.Contains(SearchString));
}

s => s.Title.Contains() 程式碼是一種 Lambda 運算式。 在以方法為基礎的 LINQ 查詢中,Lambda 會用來作為標準查詢運算子方法的引數,例如 Where 方法或 Contains。 定義 LINQ 查詢或藉由呼叫像是 WhereContainsOrderBy 等方法進行修改時,並不會執行查詢。 而是會延後查詢執行。 運算式的評估會延遲直到該運算式的實現值受到逐一查看,或呼叫 ToListAsync 方法為止。 如需詳細資訊,請參閱查詢執行

注意

Contains 方法是在資料庫上執行,而不是在 C# 程式碼中執行。 查詢的區分大小寫取決於資料庫和定序。 在 SQL Server 上,Contains 對應至 SQL LIKE,因此不區分大小寫。 根據查詢,具有預設定序的 SQLite 是區分大小寫和區分大小寫的組合。 如需不區分大小寫 SQLite 查詢的相關資訊,請參閱下列內容:

流覽至 [電影] 頁面,並將查詢字串附加至 URL,例如 ?searchString=Ghost。 例如: https://localhost:5001/Movies?searchString=Ghost 。 隨即顯示篩選過的電影。

索引檢視

如果您已將下列路由範本新增至 Index 頁面,即可透過 URL 區段的形式來傳遞搜尋字串。 例如: https://localhost:5001/Movies/Ghost

@page "{searchString?}"

上述的路由條件約束可讓您以路由資料的形式 (URL 區段) 搜尋標題,而不是以查詢字串值的形式。 在 ? 中,"{searchString?}" 表示此為選擇性的路由參數。

索引檢視,其中已將 ghost 一詞新增至 URL,而傳回的電影清單包含 Ghostbusters 和 Ghostbusters 2 兩部電影

ASP.NET Core 執行階段使用模型繫結來設定查詢字串 (?searchString=Ghost) 中的 SearchString 屬性值或路由傳送資料 (https://localhost:5001/Movies/Ghost)。 模型繫結是區分大小寫的。

但是,無法預期使用者修改 URL 來搜尋電影。 在此步驟中,會新增用來篩選電影的 UI。 如果您已新增路由條件約束 "{searchString?}",請將它移除。

開啟 Pages/Movies/Index.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> 標籤會使用下列標籤協助程式

儲存變更並測試篩選條件。

已將 ghost 一詞輸入 [標題] 篩選條件文字方塊的 Index 檢視

依內容類型搜尋

使用下列程式碼來更新 Index 頁面的 OnGetAsync 方法:

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 查詢,其會從資料庫中擷取所有的內容類型。

// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
                                orderby m.Genre
                                select m.Genre;

內容類型的 SelectList 是由投影不同的內容類型來建立。

Genres = new SelectList(await genreQuery.Distinct().ToListAsync());

將依內容類型搜尋新增至 Razor 頁面

更新 Index.cshtml<form> 元素,如下列標記中所醒目提示:

@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>

依據內容類型、電影標題和這兩者進行搜尋,藉以測試應用程式。

下一步

在下列各節中,會新增依「內容類型」或「名稱」搜尋電影。

將下列醒目提示的 using 陳述式和屬性新增至 Pages/Movies/Index.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{

    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IList<Movie> Movie { get; set; }
        [BindProperty(SupportsGet = true)]
        public string SearchString { get; set; }
        public SelectList Genres { get; set; }
        [BindProperty(SupportsGet = true)]
        public string MovieGenre { get; set; }

在先前的程式碼中:

  • SearchString:包含使用者在搜尋文字方塊中輸入的文字。 SearchString 具有 [BindProperty] 屬性。 [BindProperty] 使用與屬性相同的名稱來繫結表單值和查詢字串。 需要 [BindProperty(SupportsGet = true)] 才能在 HTTP GET 要求上進行繫結。
  • Genres:包含內容類型清單。 Genres 可讓使用者從清單中選取內容類型。 SelectList 需要 using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre:包含使用者所選取的特定內容類型。 例如「西部片」。
  • 稍後在本教學課程中將會使用 GenresMovieGenre

警告

基於安全性考量,您必須選擇將 GET 要求資料繫結到頁面模型屬性。 請先驗證使用者輸入再將其對應至屬性。 在解決仰賴查詢字串或路由值的案例時,選擇使用 GET 繫結會很有幫助。

若要在 GET 要求上繫結屬性,請將 [BindProperty] 屬性的 SupportsGet 屬性設定為 true

[BindProperty(SupportsGet = true)]

如需詳細資訊,請參閱 ASP.NET Core Community Standup: Bind on GET discussion (YouTube)

使用下列程式碼來更新 Index 頁面的 OnGetAsync 方法:

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 方法的第一行會建立 LINQ 查詢,以選取電影:

// using System.Linq;
var movies = from m in _context.Movie
             select m;

這時候,系統只會「定義」查詢,而尚對資料庫執行查詢。

如果 SearchString 屬性不是 Null 或空白,則會修改電影查詢來篩選搜尋字串:

if (!string.IsNullOrEmpty(SearchString))
{
    movies = movies.Where(s => s.Title.Contains(SearchString));
}

s => s.Title.Contains() 程式碼是一種 Lambda 運算式。 在以方法為基礎的 LINQ 查詢中,Lambda 會用來作為標準查詢運算子方法的引數,例如 Where 方法或 Contains。 定義 LINQ 查詢或藉由呼叫像是 WhereContainsOrderBy 等方法進行修改時,並不會執行查詢。 而是會延後查詢執行。 運算式的評估會延遲直到該運算式的實現值受到逐一查看,或呼叫 ToListAsync 方法為止。 如需詳細資訊,請參閱查詢執行

注意

Contains 方法是在資料庫上執行,而不是在 C# 程式碼中執行。 查詢的區分大小寫取決於資料庫和定序。 在 SQL Server 上,Contains 對應至 SQL LIKE,因此不區分大小寫。 根據查詢,具有預設定序的 SQLite 是區分大小寫和區分大小寫的組合。 如需不區分大小寫 SQLite 查詢的相關資訊,請參閱下列內容:

流覽至 [電影] 頁面,並將查詢字串附加至 URL,例如 ?searchString=Ghost。 例如: https://localhost:5001/Movies?searchString=Ghost 。 隨即顯示篩選過的電影。

索引檢視

如果您已將下列路由範本新增至 Index 頁面,即可透過 URL 區段的形式來傳遞搜尋字串。 例如: https://localhost:5001/Movies/Ghost

@page "{searchString?}"

上述的路由條件約束可讓您以路由資料的形式 (URL 區段) 搜尋標題,而不是以查詢字串值的形式。 在 ? 中,"{searchString?}" 表示此為選擇性的路由參數。

索引檢視,其中已將 ghost 一詞新增至 URL,而傳回的電影清單包含 Ghostbusters 和 Ghostbusters 2 兩部電影

ASP.NET Core 執行階段使用模型繫結來設定查詢字串 (?searchString=Ghost) 中的 SearchString 屬性值或路由傳送資料 (https://localhost:5001/Movies/Ghost)。 模型繫結是區分大小寫的。

但是,無法預期使用者修改 URL 來搜尋電影。 在此步驟中,會新增用來篩選電影的 UI。 如果您已新增路由條件約束 "{searchString?}",請將它移除。

開啟 Pages/Movies/Index.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> 標籤會使用下列標籤協助程式

儲存變更並測試篩選條件。

已將 ghost 一詞輸入 [標題] 篩選條件文字方塊的 Index 檢視

依內容類型搜尋

使用下列程式碼來更新 Index 頁面的 OnGetAsync 方法:

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 查詢,其會從資料庫中擷取所有的內容類型。

// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
                                orderby m.Genre
                                select m.Genre;

內容類型的 SelectList 是由投影不同的內容類型來建立。

Genres = new SelectList(await genreQuery.Distinct().ToListAsync());

將依內容類型搜尋新增至 Razor 頁面

  1. 更新 Index.cshtml<form> 元素,如下列標記中所醒目提示:

    @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.*@
    
    
  2. 依據內容類型、電影標題和這兩者進行搜尋,藉以測試應用程式。

下一步