将搜索添加到 ASP.NET Core Razor 页面Add search to ASP.NET Core Razor Pages

本文内容

作者:Rick Anderson

查看或下载示例代码如何下载)。

查看或下载示例代码如何下载)。

在以下部分中,添加了按流派 或名称 搜索电影。

将以下突出显示的属性添加到 Pages/Movies/Index.cshtml.cs :

  1. public class IndexModel : PageModel
  2. {
  3. private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;
  4. public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
  5. {
  6. _context = context;
  7. }
  8. public IList<Movie> Movie { get; set; }
  9. [BindProperty(SupportsGet = true)]
  10. public string SearchString { get; set; }
  11. // Requires using Microsoft.AspNetCore.Mvc.Rendering;
  12. public SelectList Genres { get; set; }
  13. [BindProperty(SupportsGet = true)]
  14. public string MovieGenre { get; set; }
  • SearchString:包含用户在搜索文本框中输入的文本。SearchString 也有 [BindProperty] 属性。[BindProperty] 会绑定名称与属性相同的表单值和查询字符串。在 GET 请求中进行绑定需要 (SupportsGet = true)
  • Genres:包含流派列表。Genres 使用户能够从列表中选择一种流派。SelectList 需要 using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre:包含用户选择的特定流派(例如“西部”)。
  • GenresMovieGenre 会在本教程的后续部分中使用。

警告

出于安全原因,必须选择绑定 GET 请求数据以对模型属性进行分页。请在将用户输入映射到属性前对其进行验证。当处理依赖查询字符串或路由值的方案时,选择加入 GET 绑定非常有用。

若要将属性绑定在 GET 请求上,请将 [BindProperty] 特性的 SupportsGet 属性设置为 true

  1. [BindProperty(SupportsGet = true)]

有关详细信息,请参阅 ASP.NET Core Community Standup:Bind on GET discussion (YouTube)(绑定 GET 讨论)。

使用以下代码更新索引页面的 OnGetAsync 方法:

  1. public async Task OnGetAsync()
  2. {
  3. var movies = from m in _context.Movie
  4. select m;
  5. if (!string.IsNullOrEmpty(SearchString))
  6. {
  7. movies = movies.Where(s => s.Title.Contains(SearchString));
  8. }
  9. Movie = await movies.ToListAsync();
  10. }

OnGetAsync 方法的第一行创建了 LINQ 查询用于选择电影:

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

此时仅对查询进行了定义,它还不会针对数据库运行 。

如果 SearchString 属性不为 null 或空,则电影查询会修改为根据搜索字符串进行筛选:

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

s => s.Title.Contains() 代码是 Lambda 表达式Lambda 在基于方法的 LINQ 查询中用作标准查询运算符方法的参数,如 Where 方法或 Contains(前面的代码中所使用的)。在对 LINQ 查询进行定义或通过调用方法(如 WhereContainsOrderBy)进行修改后,此查询不会被执行。相反,会延迟执行查询。这意味着表达式的计算会延迟,直到循环访问其实现的值或者调用 ToListAsync 方法为止。有关详细信息,请参阅 Query Execution(查询执行)。

备注

Contains 方法在数据库中运行,而不是在 C# 代码中运行。查询是否区分大小写取决于数据库和排序规则。在 SQL Server 上,Contains 映射到 SQL LIKE,这是不区分大小写的。在 SQLite 中,由于使用了默认排序规则,因此需要区分大小写。

导航到电影页面,并向 URL追加一个如 ?searchString=Ghost 的查询字符串(例如 https://localhost:5001/Movies?searchString=Ghost)。筛选的电影将显示出来。

索引视图

如果向索引页面添加了以下路由模板,搜索字符串则可作为 URL 段传递(例如 https://localhost:5001/Movies/Ghost)。

  1. @page "{searchString?}"

前面的路由约束允许按路由数据(URL 段)搜索标题,而不是按查询字符串值进行搜索。"{searchString?}" 中的 ? 表示这是可选路由参数。

索引视图,显示添加到 URL 的“ghost”一词以及返回的两部电影(Ghostbusters 和 Ghostbusters 2)的电影列表

ASP.NET Core 运行时使用模型绑定,通过查询字符串 (?searchString=Ghost) 或路由数据 (https://localhost:5001/Movies/Ghost) 设置 SearchString 属性的值。模型绑定搜索不区分大小写。

但是,不能指望用户修改 URL 来搜索电影。在此步骤中,会添加 UI 来筛选电影。如果已添加路由约束 "{searchString?}",请将它删除。

打开 Pages/Movies/Index.cshtml 文件,并添加以下代码中突出显示的 <form> 标记 :

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.IndexModel
  3. @{
  4. ViewData["Title"] = "Index";
  5. }
  6. <h1>Index</h1>
  7. <p>
  8. <a asp-page="Create">Create New</a>
  9. </p>
  10. <form>
  11. <p>
  12. Title: <input type="text" asp-for="SearchString" />
  13. <input type="submit" value="Filter" />
  14. </p>
  15. </form>
  16. <table class="table">
  17. @*Markup removed for brevity.*@

HTML <form> 标记使用以下标记帮助程序

保存更改并测试筛选器。

显示标题筛选器文本框中键入了 ghost 一词的索引视图

按流派搜索Search by genre

使用以下代码更新 OnGetAsync 方法:

  1. public async Task OnGetAsync()
  2. {
  3. // Use LINQ to get list of genres.
  4. IQueryable<string> genreQuery = from m in _context.Movie
  5. orderby m.Genre
  6. select m.Genre;
  7. var movies = from m in _context.Movie
  8. select m;
  9. if (!string.IsNullOrEmpty(SearchString))
  10. {
  11. movies = movies.Where(s => s.Title.Contains(SearchString));
  12. }
  13. if (!string.IsNullOrEmpty(MovieGenre))
  14. {
  15. movies = movies.Where(x => x.Genre == MovieGenre);
  16. }
  17. Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
  18. Movie = await movies.ToListAsync();
  19. }

下面的代码是一种 LINQ 查询,可从数据库中检索所有流派。

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

流派的 SelectList 是通过投影不包含重复值的流派创建的。

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

将按流派搜索添加到 Razor 页面Add search by genre to the Razor Page

更新 Index.cshtml,如下所示 :

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.IndexModel
  3. @{
  4. ViewData["Title"] = "Index";
  5. }
  6. <h1>Index</h1>
  7. <p>
  8. <a asp-page="Create">Create New</a>
  9. </p>
  10. <form>
  11. <p>
  12. <select asp-for="MovieGenre" asp-items="Model.Genres">
  13. <option value="">All</option>
  14. </select>
  15. Title: <input type="text" asp-for="SearchString" />
  16. <input type="submit" value="Filter" />
  17. </p>
  18. </form>
  19. <table class="table">
  20. @*Markup removed for brevity.*@

通过按流派或/和电影标题搜索来测试应用。

其他资源Additional resources

上一篇:更新页面下一篇:添加新字段

查看或下载示例代码如何下载)。

查看或下载示例代码如何下载)。

在以下部分中,添加了按流派 或名称 搜索电影。

将以下突出显示的属性添加到 Pages/Movies/Index.cshtml.cs :

  1. public class IndexModel : PageModel
  2. {
  3. private readonly RazorPagesMovie.Models.RazorPagesMovieContext _context;
  4. public IndexModel(RazorPagesMovie.Models.RazorPagesMovieContext context)
  5. {
  6. _context = context;
  7. }
  8. public IList<Movie> Movie { get; set; }
  9. [BindProperty(SupportsGet = true)]
  10. public string SearchString { get; set; }
  11. // Requires using Microsoft.AspNetCore.Mvc.Rendering;
  12. public SelectList Genres { get; set; }
  13. [BindProperty(SupportsGet = true)]
  14. public string MovieGenre { get; set; }
  • SearchString:包含用户在搜索文本框中输入的文本。SearchString 也有 [BindProperty] 属性。[BindProperty] 会绑定名称与属性相同的表单值和查询字符串。在 GET 请求中进行绑定需要 (SupportsGet = true)
  • Genres:包含流派列表。Genres 使用户能够从列表中选择一种流派。SelectList 需要 using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre:包含用户选择的特定流派(例如“西部”)。
  • GenresMovieGenre 会在本教程的后续部分中使用。

警告

出于安全原因,必须选择绑定 GET 请求数据以对模型属性进行分页。请在将用户输入映射到属性前对其进行验证。当处理依赖查询字符串或路由值的方案时,选择加入 GET 绑定非常有用。

若要将属性绑定在 GET 请求上,请将 [BindProperty] 特性的 SupportsGet 属性设置为 true

  1. [BindProperty(SupportsGet = true)]

有关详细信息,请参阅 ASP.NET Core Community Standup:Bind on GET discussion (YouTube)(绑定 GET 讨论)。

使用以下代码更新索引页面的 OnGetAsync 方法:

  1. public async Task OnGetAsync()
  2. {
  3. var movies = from m in _context.Movie
  4. select m;
  5. if (!string.IsNullOrEmpty(SearchString))
  6. {
  7. movies = movies.Where(s => s.Title.Contains(SearchString));
  8. }
  9. Movie = await movies.ToListAsync();
  10. }

OnGetAsync 方法的第一行创建了 LINQ 查询用于选择电影:

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

此时仅对查询进行了定义,它还不会针对数据库运行 。

如果 SearchString 属性不为 null 或空,则电影查询会修改为根据搜索字符串进行筛选:

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

s => s.Title.Contains() 代码是 Lambda 表达式Lambda 在基于方法的 LINQ 查询中用作标准查询运算符方法的参数,如 Where 方法或 Contains(前面的代码中所使用的)。在对 LINQ 查询进行定义或通过调用方法(如 WhereContainsOrderBy)进行修改后,此查询不会被执行。相反,会延迟执行查询。这意味着表达式的计算会延迟,直到循环访问其实现的值或者调用 ToListAsync 方法为止。有关详细信息,请参阅 Query Execution(查询执行)。

注意:Contains 方法在数据库中运行,而不是在 C# 代码中运行。查询是否区分大小写取决于数据库和排序规则。在 SQL Server 上,Contains 映射到 SQL LIKE,这是不区分大小写的。在 SQLite 中,由于使用了默认排序规则,因此需要区分大小写。

导航到电影页面,并向 URL追加一个如 ?searchString=Ghost 的查询字符串(例如 https://localhost:5001/Movies?searchString=Ghost)。筛选的电影将显示出来。

索引视图

如果向索引页面添加了以下路由模板,搜索字符串则可作为 URL 段传递(例如 https://localhost:5001/Movies/Ghost)。

  1. @page "{searchString?}"

前面的路由约束允许按路由数据(URL 段)搜索标题,而不是按查询字符串值进行搜索。"{searchString?}" 中的 ? 表示这是可选路由参数。

索引视图,显示添加到 URL 的“ghost”一词以及返回的两部电影(Ghostbusters 和 Ghostbusters 2)的电影列表

ASP.NET Core 运行时使用模型绑定,通过查询字符串 (?searchString=Ghost) 或路由数据 (https://localhost:5001/Movies/Ghost) 设置 SearchString 属性的值。模型绑定搜索不区分大小写。

但是,不能指望用户修改 URL 来搜索电影。在此步骤中,会添加 UI 来筛选电影。如果已添加路由约束 "{searchString?}",请将它删除。

打开 Pages/Movies/Index.cshtml 文件,并添加以下代码中突出显示的 <form> 标记 :

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.IndexModel
  3. @{
  4. ViewData["Title"] = "Index";
  5. }
  6. <h1>Index</h1>
  7. <p>
  8. <a asp-page="Create">Create New</a>
  9. </p>
  10. <form>
  11. <p>
  12. Title: <input type="text" asp-for="SearchString" />
  13. <input type="submit" value="Filter" />
  14. </p>
  15. </form>
  16. <table class="table">
  17. @*Markup removed for brevity.*@

HTML <form> 标记使用以下标记帮助程序

保存更改并测试筛选器。

显示标题筛选器文本框中键入了 ghost 一词的索引视图

按流派搜索Search by genre

使用以下代码更新 OnGetAsync 方法:

  1. public async Task OnGetAsync()
  2. {
  3. // Use LINQ to get list of genres.
  4. IQueryable<string> genreQuery = from m in _context.Movie
  5. orderby m.Genre
  6. select m.Genre;
  7. var movies = from m in _context.Movie
  8. select m;
  9. if (!string.IsNullOrEmpty(SearchString))
  10. {
  11. movies = movies.Where(s => s.Title.Contains(SearchString));
  12. }
  13. if (!string.IsNullOrEmpty(MovieGenre))
  14. {
  15. movies = movies.Where(x => x.Genre == MovieGenre);
  16. }
  17. Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
  18. Movie = await movies.ToListAsync();
  19. }

下面的代码是一种 LINQ 查询,可从数据库中检索所有流派。

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

流派的 SelectList 是通过投影不包含重复值的流派创建的。

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

将按流派搜索添加到 Razor 页面Add search by genre to the Razor Page

更新 Index.cshtml,如下所示 :

  1. @page
  2. @model RazorPagesMovie.Pages.Movies.IndexModel
  3. @{
  4. ViewData["Title"] = "Index";
  5. }
  6. <h1>Index</h1>
  7. <p>
  8. <a asp-page="Create">Create New</a>
  9. </p>
  10. <form>
  11. <p>
  12. <select asp-for="MovieGenre" asp-items="Model.Genres">
  13. <option value="">All</option>
  14. </select>
  15. Title: <input type="text" asp-for="SearchString" />
  16. <input type="submit" value="Filter" />
  17. </p>
  18. </form>
  19. <table class="table">
  20. @*Markup removed for brevity.*@

通过按流派或/和电影标题搜索来测试应用。前面的代码使用选择标记帮助程序和选项标记帮助程序。

其他资源Additional resources

上一篇:更新页面下一篇:添加新字段