Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Примечание.
Это не последняя версия этой статьи. В текущей версии см. версию .NET 10 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущей версии см. версию .NET 10 этой статьи.
Автор: Рик Андерсон (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: содержит определенный жанр, который выбирает пользователь. Например, "Боевик". -
GenresиMovieGenreрассматриваются позднее в этом учебнике.
Предупреждение
В целях безопасности вам следует задать привязку данных запроса GET к свойствам страничной модели. Проверьте введенные данные пользователя, прежде чем сопоставлять их со свойствами. Привязка GET полезна при обращении к сценариям, использующим строку запроса или значения маршрутов.
Чтобы привязать свойство к запросам GET, задайте для свойства [BindProperty] атрибута SupportsGet значение true:
[BindProperty(SupportsGet = true)]
Дополнительные сведения: ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Обновите метод Movies/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 для выбора фильмов:
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() представляет собой лямбда-выражение. Лямбда-выражения используются в запросах LINQ на основе методов в качестве аргументов стандартных методов операторов запроса, таких как метод Where или Contains. Запросы LINQ не выполняются при их определении или изменении путем вызова метода, например Where, Containsили OrderBy. Вместо этого выполнение запроса откладывается. Вычисление выражения откладывается до тех пор, пока не будет выполнена итерация его реализованного значения или не будет вызван метод ToListAsync. Дополнительные сведения см. в разделе "Выполнение запросов".
Примечание.
Метод Contains выполняется в базе данных, а не в коде C#. Регистр символов запроса учитывается в зависимости от параметров базы данных и сортировки. В SQL Server метод Contains сопоставляется с SQL LIKE, в котором регистр символов не учитывается. SQLite с параметрами сортировки по умолчанию — это смесь параметров с учетом регистра и параметров, которые НЕ учитывают регистр, в зависимости от запроса. Сведения о том, как выполнять запросы SQLite, которые не учитывают регистр, см. в следующих статьях:
Перейдите на страницу Movies и добавьте строку запроса, например ?searchString=Ghost, к URL-адресу. Например, https://localhost:7247/Movies?searchString=Ghost. Отображаются отфильтрованные фильмы.
При добавлении следующего шаблона маршрута на страницу индекса можно передать строку поиска в виде сегмента URL-адреса. Например, https://localhost:7247/Movies/Ghost.
@page "{searchString?}"
Предыдущее ограничение маршрута разрешало поиск названия в виде данных маршрута (сегмент URL-адреса) вместо значения строки запроса. Символ ? в "{searchString?}" означает, что этот параметр является необязательным.
Среда выполнения ASP.NET Core использует привязку модели, чтобы присвоить значение свойства SearchString по строке запроса (?searchString=Ghost) или данным маршрута (https://localhost:7247/Movies/Ghost). Привязка модели не учитывает регистр.
Однако пользователям не может потребоваться изменить URL-адрес для поиска фильма. На этом шаге вы добавите пользовательский интерфейс для фильтрации фильмов. Если было добавлено ограничение маршрута "{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>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
<thead>
Тег HTML <form> использует следующие вспомогательные функции тегов:
- вспомогательная функция тега форм. При отправке формы она отправляет строку фильтра на страницу Pages/Movies/Index через строку запроса.
- Вспомогательная функция тега Input
Сохраните изменения и проверьте фильтр.
Поиск по жанру
Movies/Index.cshtml.cs Обновите метод страницы OnGetAsync следующим кодом:
public async Task OnGetAsync()
{
// <snippet_search_linqQuery>
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
// </snippet_search_linqQuery>
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);
}
// <snippet_search_selectList>
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
// </snippet_search_selectList>
Movie = await movies.ToListAsync();
}
Следующий код определяет запрос LINQ, который извлекает все жанры из базы данных.
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>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<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: содержит определенный жанр, который выбирает пользователь. Например, "Боевик". -
GenresиMovieGenreрассматриваются позднее в этом учебнике.
Предупреждение
В целях безопасности вам следует задать привязку данных запроса GET к свойствам страничной модели. Проверьте введенные данные пользователя, прежде чем сопоставлять их со свойствами. Привязка GET полезна при обращении к сценариям, использующим строку запроса или значения маршрутов.
Чтобы привязать свойство к запросам GET, задайте для свойства [BindProperty] атрибута SupportsGet значение true:
[BindProperty(SupportsGet = true)]
Дополнительные сведения: ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Обновите метод Movies/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 для выбора фильмов:
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() представляет собой лямбда-выражение. Лямбда-выражения используются в запросах LINQ на основе методов в качестве аргументов стандартных методов операторов запроса, таких как метод Where или Contains. Запросы LINQ не выполняются, если они определяются или изменяются путем вызова метода, например Where, Containsили OrderBy. Вместо этого выполнение запроса откладывается. Вычисление выражения откладывается до тех пор, пока не будет выполнена итерация его реализованного значения или не будет вызван метод ToListAsync. Дополнительные сведения см. в разделе Выполнение запроса.
Примечание.
Метод Contains выполняется в базе данных, а не в коде C#. Регистр символов запроса учитывается в зависимости от параметров базы данных и сортировки. В SQL Server метод Contains сопоставляется с SQL LIKE, в котором регистр символов не учитывается. SQLite с параметрами сортировки по умолчанию — это смесь параметров с учетом регистра и параметров, которые НЕ учитывают регистр, в зависимости от запроса. Сведения о том, как выполнять запросы SQLite, которые не учитывают регистр, см. в следующих статьях:
Перейдите на страницу Movies и добавьте строку запроса, например ?searchString=Ghost, к URL-адресу. Например, https://localhost:5001/Movies?searchString=Ghost. Отображаются отфильтрованные фильмы.
Если на страницу Index добавлен следующий шаблон маршрута, строку поиска можно передать в виде сегмента URL-адреса. Например, https://localhost:5001/Movies/Ghost.
@page "{searchString?}"
Предыдущее ограничение маршрута разрешало поиск названия в виде данных маршрута (сегмент URL-адреса) вместо значения строки запроса. Символ ? в "{searchString?}" означает, что этот параметр является необязательным.
Среда выполнения ASP.NET Core использует привязку модели, чтобы присвоить значение свойства SearchString по строке запроса (?searchString=Ghost) или данным маршрута (https://localhost:5001/Movies/Ghost). Привязка модели не учитывает регистр символов.
Однако пользователи не могут изменять URL-адрес для поиска фильма. На этом шаге добавляется пользовательский интерфейс для поиска фильмов. Если было добавлено ограничение маршрута "{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>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
<thead>
Тег HTML <form> использует следующие вспомогательные функции тегов:
- вспомогательная функция тега форм. При отправке формы строка фильтра отправляется на страницу Pages/Movies/Index в строке запроса.
- Вспомогательная функция тега Input
Сохраните изменения и проверьте работу фильтра.
Поиск по жанру
Movies/Index.cshtml.cs Обновите метод страницы OnGetAsync следующим кодом:
public async Task OnGetAsync()
{
// <snippet_search_linqQuery>
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
// </snippet_search_linqQuery>
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);
}
// <snippet_search_selectList>
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
// </snippet_search_selectList>
Movie = await movies.ToListAsync();
}
Следующий код определяет запрос LINQ, который извлекает все жанры из базы данных.
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>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<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: содержит определенный жанр, который выбирает пользователь. Например, "Боевик". -
GenresиMovieGenreрассматриваются позднее в этом учебнике.
Предупреждение
В целях безопасности вам следует задать привязку данных запроса GET к свойствам страничной модели. Проверьте введенные данные пользователя, прежде чем сопоставлять их со свойствами. Привязка GET полезна при обращении к сценариям, использующим строку запроса или значения маршрутов.
Чтобы привязать свойство к запросам GET, задайте для свойства [BindProperty] атрибута SupportsGet значение true:
[BindProperty(SupportsGet = true)]
Дополнительные сведения: ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Обновите метод OnGetAsync страницы Index, добавив следующий код:
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() представляет собой лямбда-выражение. Лямбда-выражения используются в запросах LINQ на основе методов в качестве аргументов стандартных методов операторов запроса, таких как метод Where или Contains. Запросы LINQ не выполняются, если они определяются или изменяются путем вызова метода, например Where, Containsили OrderBy. Вместо этого выполнение запроса откладывается. Вычисление выражения откладывается до тех пор, пока не будет выполнена итерация его реализованного значения или не будет вызван метод ToListAsync. Дополнительные сведения см. в разделе Выполнение запроса.
Примечание.
Метод Contains выполняется в базе данных, а не в коде C#. Регистр символов запроса учитывается в зависимости от параметров базы данных и сортировки. В SQL Server метод Contains сопоставляется с SQL LIKE, в котором регистр символов не учитывается. SQLite с параметрами сортировки по умолчанию — это смесь параметров с учетом регистра и параметров, которые НЕ учитывают регистр, в зависимости от запроса. Сведения о том, как выполнять запросы SQLite, которые не учитывают регистр, см. в следующих статьях:
Перейдите на страницу Movies и добавьте строку запроса, например ?searchString=Ghost, к URL-адресу. Например, https://localhost:5001/Movies?searchString=Ghost. Отображаются отфильтрованные фильмы.
Если на страницу Index добавлен следующий шаблон маршрута, строку поиска можно передать в виде сегмента URL-адреса. Например, https://localhost:5001/Movies/Ghost.
@page "{searchString?}"
Предыдущее ограничение маршрута разрешало поиск названия в виде данных маршрута (сегмент URL-адреса) вместо значения строки запроса. Символ ? в "{searchString?}" означает, что этот параметр является необязательным.
Среда выполнения ASP.NET Core использует привязку модели, чтобы присвоить значение свойства SearchString по строке запроса (?searchString=Ghost) или данным маршрута (https://localhost:5001/Movies/Ghost). Привязка модели не учитывает регистр символов.
Однако пользователи не могут изменять URL-адрес для поиска фильма. На этом шаге добавляется пользовательский интерфейс для поиска фильмов. Если было добавлено ограничение маршрута "{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>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
@*Markup removed for brevity.*@
Тег HTML <form> использует следующие вспомогательные функции тегов:
- вспомогательная функция тега форм. При отправке формы строка фильтра отправляется на страницу Pages/Movies/Index в строке запроса.
- Вспомогательная функция тега Input
Сохраните изменения и проверьте работу фильтра.
Поиск по жанру
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>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<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: содержит определенный жанр, который выбирает пользователь. Например, "Боевик". -
GenresиMovieGenreрассматриваются позднее в этом учебнике.
Предупреждение
В целях безопасности вам следует задать привязку данных запроса GET к свойствам страничной модели. Проверьте введенные данные пользователя, прежде чем сопоставлять их со свойствами. Привязка GET полезна при обращении к сценариям, использующим строку запроса или значения маршрутов.
Чтобы привязать свойство к запросам GET, задайте для свойства [BindProperty] атрибута SupportsGet значение true:
[BindProperty(SupportsGet = true)]
Дополнительные сведения: ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Обновите метод OnGetAsync страницы Index, добавив следующий код:
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() представляет собой лямбда-выражение. Лямбда-выражения используются в запросах LINQ на основе методов в качестве аргументов стандартных методов операторов запроса, таких как метод Where или Contains. Запросы LINQ не выполняются, если они определяются или изменяются путем вызова метода, например Where, Containsили OrderBy. Вместо этого выполнение запроса откладывается. Вычисление выражения откладывается до тех пор, пока не будет выполнена итерация его реализованного значения или не будет вызван метод ToListAsync. Дополнительные сведения см. в разделе Выполнение запроса.
Примечание.
Метод Contains выполняется в базе данных, а не в коде C#. Регистр символов запроса учитывается в зависимости от параметров базы данных и сортировки. В SQL Server метод Contains сопоставляется с SQL LIKE, в котором регистр символов не учитывается. SQLite с параметрами сортировки по умолчанию — это смесь параметров с учетом регистра и параметров, которые НЕ учитывают регистр, в зависимости от запроса. Сведения о том, как выполнять запросы SQLite, которые не учитывают регистр, см. в следующих статьях:
Перейдите на страницу Movies и добавьте строку запроса, например ?searchString=Ghost, к URL-адресу. Например, https://localhost:5001/Movies?searchString=Ghost. Отображаются отфильтрованные фильмы.
Если на страницу Index добавлен следующий шаблон маршрута, строку поиска можно передать в виде сегмента URL-адреса. Например, https://localhost:5001/Movies/Ghost.
@page "{searchString?}"
Предыдущее ограничение маршрута разрешало поиск названия в виде данных маршрута (сегмент URL-адреса) вместо значения строки запроса. Символ ? в "{searchString?}" означает, что этот параметр является необязательным.
Среда выполнения ASP.NET Core использует привязку модели, чтобы присвоить значение свойства SearchString по строке запроса (?searchString=Ghost) или данным маршрута (https://localhost:5001/Movies/Ghost). Привязка модели не учитывает регистр символов.
Однако пользователи не могут изменять URL-адрес для поиска фильма. На этом шаге добавляется пользовательский интерфейс для поиска фильмов. Если было добавлено ограничение маршрута "{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>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
@*Markup removed for brevity.*@
Тег HTML <form> использует следующие вспомогательные функции тегов:
- вспомогательная функция тега форм. При отправке формы строка фильтра отправляется на страницу Pages/Movies/Index в строке запроса.
- Вспомогательная функция тега Input
Сохраните изменения и проверьте работу фильтра.
Поиск по жанру
Обновите метод OnGetAsync страницы Index, добавив следующий код:
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>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<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: содержит определенный жанр, который выбирает пользователь. Например, "Боевик". -
GenresиMovieGenreрассматриваются позднее в этом учебнике.
Предупреждение
В целях безопасности вам следует задать привязку данных запроса GET к свойствам страничной модели. Проверьте введенные данные пользователя, прежде чем сопоставлять их со свойствами. Привязка GET полезна при обращении к сценариям, использующим строку запроса или значения маршрутов.
Чтобы привязать свойство к запросам GET, задайте для свойства [BindProperty] атрибута SupportsGet значение true:
[BindProperty(SupportsGet = true)]
Дополнительные сведения: ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Обновите метод OnGetAsync страницы Index, добавив следующий код:
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() представляет собой лямбда-выражение. Лямбда-выражения используются в запросах LINQ на основе методов в качестве аргументов стандартных методов операторов запроса, таких как метод Where или Contains. Запросы LINQ не выполняются, если они определяются или изменяются путем вызова метода, например Where, Containsили OrderBy. Вместо этого выполнение запроса откладывается. Вычисление выражения откладывается до тех пор, пока не будет выполнена итерация его реализованного значения или не будет вызван метод ToListAsync. Дополнительные сведения см. в разделе Выполнение запроса.
Примечание.
Метод Contains выполняется в базе данных, а не в коде C#. Регистр символов запроса учитывается в зависимости от параметров базы данных и сортировки. В SQL Server метод Contains сопоставляется с SQL LIKE, в котором регистр символов не учитывается. SQLite с параметрами сортировки по умолчанию — это смесь параметров с учетом регистра и параметров, которые НЕ учитывают регистр, в зависимости от запроса. Сведения о том, как выполнять запросы SQLite, которые не учитывают регистр, см. в следующих статьях:
Перейдите на страницу Movies и добавьте строку запроса, например ?searchString=Ghost, к URL-адресу. Например, https://localhost:5001/Movies?searchString=Ghost. Отображаются отфильтрованные фильмы.
Если на страницу Index добавлен следующий шаблон маршрута, строку поиска можно передать в виде сегмента URL-адреса. Например, https://localhost:5001/Movies/Ghost.
@page "{searchString?}"
Предыдущее ограничение маршрута разрешало поиск названия в виде данных маршрута (сегмент URL-адреса) вместо значения строки запроса. Символ ? в "{searchString?}" означает, что этот параметр является необязательным.
Среда выполнения ASP.NET Core использует привязку модели, чтобы присвоить значение свойства SearchString по строке запроса (?searchString=Ghost) или данным маршрута (https://localhost:5001/Movies/Ghost). Привязка модели не учитывает регистр символов.
Однако пользователи не могут изменять URL-адрес для поиска фильма. На этом шаге добавляется пользовательский интерфейс для поиска фильмов. Если было добавлено ограничение маршрута "{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>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
@*Markup removed for brevity.*@
Тег HTML <form> использует следующие вспомогательные функции тегов:
- вспомогательная функция тега форм. При отправке формы строка фильтра отправляется на страницу Pages/Movies/Index в строке запроса.
- Вспомогательная функция тега Input
Сохраните изменения и проверьте работу фильтра.
Поиск по жанру
Обновите метод OnGetAsync страницы Index, добавив следующий код:
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>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<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: содержит определенный жанр, который выбирает пользователь. Например, "Боевик". -
GenresиMovieGenreрассматриваются позднее в этом учебнике.
Предупреждение
В целях безопасности вам следует задать привязку данных запроса GET к свойствам страничной модели. Проверьте введенные данные пользователя, прежде чем сопоставлять их со свойствами. Привязка GET полезна при обращении к сценариям, использующим строку запроса или значения маршрутов.
Чтобы привязать свойство к запросам GET, задайте для свойства [BindProperty] атрибута SupportsGet значение true:
[BindProperty(SupportsGet = true)]
Дополнительные сведения: ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Обновите метод OnGetAsync страницы Index, добавив следующий код:
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() представляет собой лямбда-выражение. Лямбда-выражения используются в запросах LINQ на основе методов в качестве аргументов стандартных методов операторов запроса, таких как метод Where или Contains. Запросы LINQ не выполняются, если они определяются или изменяются путем вызова метода, например Where, Containsили OrderBy. Вместо этого выполнение запроса откладывается. Вычисление выражения откладывается до тех пор, пока не будет выполнена итерация его реализованного значения или не будет вызван метод ToListAsync. Дополнительные сведения см. в разделе Выполнение запроса.
Примечание.
Метод Contains выполняется в базе данных, а не в коде C#. Регистр символов запроса учитывается в зависимости от параметров базы данных и сортировки. В SQL Server метод Contains сопоставляется с SQL LIKE, в котором регистр символов не учитывается. SQLite с параметрами сортировки по умолчанию — это смесь параметров с учетом регистра и параметров, которые НЕ учитывают регистр, в зависимости от запроса. Сведения о том, как выполнять запросы SQLite, которые не учитывают регистр, см. в следующих статьях:
Перейдите на страницу Movies и добавьте строку запроса, например ?searchString=Ghost, к URL-адресу. Например, https://localhost:5001/Movies?searchString=Ghost. Отображаются отфильтрованные фильмы.
Если на страницу Index добавлен следующий шаблон маршрута, строку поиска можно передать в виде сегмента URL-адреса. Например, https://localhost:5001/Movies/Ghost.
@page "{searchString?}"
Предыдущее ограничение маршрута разрешало поиск названия в виде данных маршрута (сегмент URL-адреса) вместо значения строки запроса. Символ ? в "{searchString?}" означает, что этот параметр является необязательным.
Среда выполнения ASP.NET Core использует привязку модели, чтобы присвоить значение свойства SearchString по строке запроса (?searchString=Ghost) или данным маршрута (https://localhost:5001/Movies/Ghost). Привязка модели не учитывает регистр символов.
Однако пользователи не могут изменять URL-адрес для поиска фильма. На этом шаге добавляется пользовательский интерфейс для поиска фильмов. Если было добавлено ограничение маршрута "{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>
<label>Title: <input type="text" asp-for="SearchString" /></label>
<input type="submit" value="Filter" />
</p>
</form>
<table class="table">
@*Markup removed for brevity.*@
Тег HTML <form> использует следующие вспомогательные функции тегов:
- вспомогательная функция тега форм. При отправке формы строка фильтра отправляется на страницу Pages/Movies/Index в строке запроса.
- Вспомогательная функция тега Input
Сохраните изменения и проверьте работу фильтра.
Поиск по жанру
Обновите метод OnGetAsync страницы Index, добавив следующий код:
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> <label>Title: <input type="text" asp-for="SearchString" /></label> <input type="submit" value="Filter" /> </p> </form> <table class="table"> @*Markup removed for brevity.*@Проверьте работу приложения, выполнив поиск по жанру, по названию фильма и по обоим этим параметрам.
Следующие шаги
ASP.NET Core