Część 6. Dodawanie wyszukiwania do ASP.NET Core Razor Pages
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
Ważne
Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
Autor: Rick Anderson
W poniższych sekcjach dodano wyszukiwanie filmów według gatunku lub nazwy .
Dodaj następujący wyróżniony kod do :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; }
W poprzednim kodzie:
SearchString
: zawiera tekst, który użytkownicy wprowadzają w polu tekstowym wyszukiwania.SearchString
[BindProperty]
ma atrybut .[BindProperty]
Wiąże wartości formularza i ciągi zapytania o taką samą nazwę jak właściwość.[BindProperty(SupportsGet = true)]
jest wymagany do wiązania żądań HTTP GET.Genres
: zawiera listę gatunków.Genres
umożliwia użytkownikowi wybranie gatunku z listy.SelectList
Wymagausing Microsoft.AspNetCore.Mvc.Rendering;
MovieGenre
: zawiera określony gatunek wybierany przez użytkownika. Na przykład "Western".Genres
iMovieGenre
są używane w dalszej części tego samouczka.
Ostrzeżenie
Ze względów bezpieczeństwa należy wyrazić zgodę na powiązanie danych żądania GET
z właściwościami modelu strony. Przed mapowaniem danych wejściowych użytkownika na właściwości zweryfikuj je. Wyrażenie zgody na powiązanie danych GET
jest przydatne w scenariuszach, które wykorzystują ciągi zapytania lub wartości trasy.
Aby powiązać właściwość w przypadku żądań GET
, ustaw właściwość SupportsGet
atrybutu [BindProperty]
na true
:
[BindProperty(SupportsGet = true)]
Aby uzyskać więcej informacji, zobacz Podsumowanie ASP.NET Core Community Standup: dyskusja na temat powiązania z użyciem metody GET (YouTube).
Zaktualizuj metodę Movies/Index
strony OnGetAsync
przy użyciu następującego kodu:
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();
}
Pierwszy wiersz OnGetAsync
metody tworzy zapytanie LINQ w celu wybrania filmów:
var movies = from m in _context.Movie
select m;
Zapytanie jest zdefiniowane tylko w tym momencie, nie zostało ono uruchomione względem bazy danych.
SearchString
Jeśli właściwość nie null
jest pusta lub nie jest pusta, zapytanie o filmy jest modyfikowane w celu filtrowania w ciągu wyszukiwania:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Kod s => s.Title.Contains()
jest wyrażeniem lambda. Wyrażenia lambda są używane w zapytaniach LINQ opartych na metodzie jako argumentach do standardowych metod operatorów zapytań, takich jak metoda Where lub Contains
. Zapytania LINQ nie są wykonywane podczas ich definiowania lub modyfikacji przez wywołanie metody, takiej jak Where
, Contains
lub OrderBy
. Zamiast tego wykonywanie zapytań jest odroczone. Obliczanie wyrażenia jest opóźnione do momentu, aż jego zrealizowana wartość zostanie iterowana lub ToListAsync
wywołana metoda. Aby uzyskać więcej informacji, zobacz Wykonywanie zapytań.
Uwaga
Metoda Contains jest uruchamiana w bazie danych, a nie w kodzie języka C#. Ważność wielkości liter w zapytaniu zależy od bazy danych i sortowania. W programie SQL Server Contains
mapuje na sql LIKE, co jest bez uwzględniania wielkości liter. SqLite z sortowaniem domyślnym jest kombinacją wielkości liter i wielkości liter w rozróżnianiu w zależności od zapytania. Aby uzyskać informacje na temat tworzenia zapytań SQLite bez uwzględniania wielkości liter, zobacz następujące kwestie:
Przejdź do strony Filmy i dołącz ciąg zapytania, taki jak ?searchString=Ghost
adres URL. Na przykład https://localhost:5001/Movies?searchString=Ghost
. Zostaną wyświetlone przefiltrowane filmy.
Jeśli następujący szablon trasy zostanie dodany do strony Indeks, ciąg wyszukiwania można przekazać jako segment adresu URL. Na przykład https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
Powyższe ograniczenie trasy umożliwia przeszukiwanie tytułu jako danych trasy (segment adresu URL) zamiast jako wartości ciągu zapytania. Wartość ?
in "{searchString?}"
oznacza, że jest to opcjonalny parametr trasy.
Środowisko uruchomieniowe ASP.NET Core używa powiązania modelu, aby ustawić wartość SearchString
właściwości z ciągu zapytania (?searchString=Ghost
) lub danych trasy (https://localhost:5001/Movies/Ghost
). Powiązanie modelu nie uwzględnia wielkości liter.
Nie można jednak oczekiwać zmodyfikowania adresu URL w celu wyszukania filmu. W tym kroku interfejs użytkownika jest dodawany do filtrowania filmów. Jeśli dodano ograniczenie "{searchString?}"
trasy, usuń go.
Pages/Movies/Index.cshtml
Otwórz plik i dodaj znacznik wyróżniony w następującym kodzie:
@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>
Tag HTML <form>
używa następujących pomocników tagów:
- Pomocnik tagu formularza. Po przesłaniu formularza ciąg filtru jest wysyłany do strony Pages/Movies/Index za pośrednictwem ciągu zapytania.
- Pomocnik tagów danych wejściowych
Zapisz zmiany i przetestuj filtr.
Wyszukiwanie według gatunku
Zaktualizuj metodę Movies/Index.cshtml.cs
page OnGetAsync
przy użyciu następującego kodu:
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();
}
Poniższy kod to zapytanie LINQ, które pobiera wszystkie gatunki z bazy danych.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
Gatunek SelectList
jest tworzony przez projekcję odrębnych gatunków:
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Dodawanie wyszukiwania według gatunku Razor do strony
Index.cshtml
<form>
Zaktualizuj element jako wyróżniony w następującym znaczniku:
@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>
Przetestuj aplikację, wyszukując według gatunku, według tytułu filmu i przez oba:
Następne kroki
W poniższych sekcjach dodano wyszukiwanie filmów według gatunku lub nazwy .
Dodaj następujący wyróżniony kod do :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; }
W poprzednim kodzie:
SearchString
: zawiera tekst, który użytkownicy wprowadzają w polu tekstowym wyszukiwania.SearchString
[BindProperty]
ma atrybut .[BindProperty]
Wiąże wartości formularza i ciągi zapytania o taką samą nazwę jak właściwość.[BindProperty(SupportsGet = true)]
jest wymagany do wiązania żądań HTTP GET.Genres
: zawiera listę gatunków.Genres
umożliwia użytkownikowi wybranie gatunku z listy.SelectList
Wymagausing Microsoft.AspNetCore.Mvc.Rendering;
MovieGenre
: zawiera określony gatunek wybierany przez użytkownika. Na przykład "Western".Genres
iMovieGenre
są używane w dalszej części tego samouczka.
Ostrzeżenie
Ze względów bezpieczeństwa należy wyrazić zgodę na powiązanie danych żądania GET
z właściwościami modelu strony. Przed mapowaniem danych wejściowych użytkownika na właściwości zweryfikuj je. Wyrażenie zgody na powiązanie danych GET
jest przydatne w scenariuszach, które wykorzystują ciągi zapytania lub wartości trasy.
Aby powiązać właściwość w przypadku żądań GET
, ustaw właściwość SupportsGet
atrybutu [BindProperty]
na true
:
[BindProperty(SupportsGet = true)]
Aby uzyskać więcej informacji, zobacz Podsumowanie ASP.NET Core Community Standup: dyskusja na temat powiązania z użyciem metody GET (YouTube).
Zaktualizuj metodę strony indeksu OnGetAsync
przy użyciu następującego kodu:
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();
}
Pierwszy wiersz OnGetAsync
metody tworzy zapytanie LINQ w celu wybrania filmów:
// using System.Linq;
var movies = from m in _context.Movie
select m;
Zapytanie jest zdefiniowane tylko w tym momencie, nie zostało ono uruchomione względem bazy danych.
SearchString
Jeśli właściwość nie null
jest pusta lub nie jest pusta, zapytanie o filmy jest modyfikowane w celu filtrowania w ciągu wyszukiwania:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Kod s => s.Title.Contains()
jest wyrażeniem lambda. Wyrażenia lambda są używane w zapytaniach LINQ opartych na metodzie jako argumentach do standardowych metod operatorów zapytań, takich jak metoda Where lub Contains
. Zapytania LINQ nie są wykonywane podczas ich definiowania lub modyfikacji przez wywołanie metody, takiej jak Where
, Contains
lub OrderBy
. Zamiast tego wykonywanie zapytań jest odroczone. Obliczanie wyrażenia jest opóźnione do momentu, aż jego zrealizowana wartość zostanie iterowana lub ToListAsync
wywołana metoda. Aby uzyskać więcej informacji, zobacz Wykonywanie zapytań.
Uwaga
Metoda Contains jest uruchamiana w bazie danych, a nie w kodzie języka C#. Ważność wielkości liter w zapytaniu zależy od bazy danych i sortowania. W programie SQL Server Contains
mapuje na sql LIKE, co jest bez uwzględniania wielkości liter. SqLite z sortowaniem domyślnym jest kombinacją wielkości liter i wielkości liter w rozróżnianiu w zależności od zapytania. Aby uzyskać informacje na temat tworzenia zapytań SQLite bez uwzględniania wielkości liter, zobacz następujące kwestie:
Przejdź do strony Filmy i dołącz ciąg zapytania, taki jak ?searchString=Ghost
adres URL. Na przykład https://localhost:5001/Movies?searchString=Ghost
. Zostaną wyświetlone przefiltrowane filmy.
Jeśli następujący szablon trasy zostanie dodany do strony Indeks, ciąg wyszukiwania można przekazać jako segment adresu URL. Na przykład https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
Powyższe ograniczenie trasy umożliwia przeszukiwanie tytułu jako danych trasy (segment adresu URL) zamiast jako wartości ciągu zapytania. Wartość ?
in "{searchString?}"
oznacza, że jest to opcjonalny parametr trasy.
Środowisko uruchomieniowe ASP.NET Core używa powiązania modelu, aby ustawić wartość SearchString
właściwości z ciągu zapytania (?searchString=Ghost
) lub danych trasy (https://localhost:5001/Movies/Ghost
). Powiązanie modelu nie uwzględnia wielkości liter.
Nie można jednak oczekiwać zmodyfikowania adresu URL w celu wyszukania filmu. W tym kroku interfejs użytkownika jest dodawany do filtrowania filmów. Jeśli dodano ograniczenie "{searchString?}"
trasy, usuń go.
Pages/Movies/Index.cshtml
Otwórz plik i dodaj znacznik wyróżniony w następującym kodzie:
@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.*@
Tag HTML <form>
używa następujących pomocników tagów:
- Pomocnik tagu formularza. Po przesłaniu formularza ciąg filtru jest wysyłany do strony Pages/Movies/Index za pośrednictwem ciągu zapytania.
- Pomocnik tagów danych wejściowych
Zapisz zmiany i przetestuj filtr.
Wyszukiwanie według gatunku
Zaktualizuj metodę Movies/Index.cshtml.cs
page OnGetAsync
przy użyciu następującego kodu:
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();
}
Poniższy kod to zapytanie LINQ, które pobiera wszystkie gatunki z bazy danych.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
Gatunek SelectList
jest tworzony przez projekcję odrębnych gatunków.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Dodawanie wyszukiwania według gatunku Razor do strony
Index.cshtml
<form>
Zaktualizuj element jako wyróżniony w następującym znaczniku:
@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>
Przetestuj aplikację, wyszukując według gatunku, według tytułu filmu i obu.
Następne kroki
W poniższych sekcjach dodano wyszukiwanie filmów według gatunku lub nazwy .
Dodaj następujący wyróżniony kod do :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; }
W poprzednim kodzie:
SearchString
: zawiera tekst, który użytkownicy wprowadzają w polu tekstowym wyszukiwania.SearchString
[BindProperty]
ma atrybut .[BindProperty]
Wiąże wartości formularza i ciągi zapytania o taką samą nazwę jak właściwość.[BindProperty(SupportsGet = true)]
jest wymagany do wiązania żądań HTTP GET.Genres
: zawiera listę gatunków.Genres
umożliwia użytkownikowi wybranie gatunku z listy.SelectList
Wymagausing Microsoft.AspNetCore.Mvc.Rendering;
MovieGenre
: zawiera określony gatunek wybierany przez użytkownika. Na przykład "Western".Genres
iMovieGenre
są używane w dalszej części tego samouczka.
Ostrzeżenie
Ze względów bezpieczeństwa należy wyrazić zgodę na powiązanie danych żądania GET
z właściwościami modelu strony. Przed mapowaniem danych wejściowych użytkownika na właściwości zweryfikuj je. Wyrażenie zgody na powiązanie danych GET
jest przydatne w scenariuszach, które wykorzystują ciągi zapytania lub wartości trasy.
Aby powiązać właściwość w przypadku żądań GET
, ustaw właściwość SupportsGet
atrybutu [BindProperty]
na true
:
[BindProperty(SupportsGet = true)]
Aby uzyskać więcej informacji, zobacz Podsumowanie ASP.NET Core Community Standup: dyskusja na temat powiązania z użyciem metody GET (YouTube).
Zaktualizuj metodę strony indeksu OnGetAsync
przy użyciu następującego kodu:
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();
}
Pierwszy wiersz OnGetAsync
metody tworzy zapytanie LINQ w celu wybrania filmów:
// using System.Linq;
var movies = from m in _context.Movie
select m;
Zapytanie jest zdefiniowane tylko w tym momencie, nie zostało ono uruchomione względem bazy danych.
SearchString
Jeśli właściwość nie null
jest pusta lub nie jest pusta, zapytanie o filmy jest modyfikowane w celu filtrowania w ciągu wyszukiwania:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Kod s => s.Title.Contains()
jest wyrażeniem lambda. Wyrażenia lambda są używane w zapytaniach LINQ opartych na metodzie jako argumentach do standardowych metod operatorów zapytań, takich jak metoda Where lub Contains
. Zapytania LINQ nie są wykonywane podczas ich definiowania lub modyfikacji przez wywołanie metody, takiej jak Where
, Contains
lub OrderBy
. Zamiast tego wykonywanie zapytań jest odroczone. Obliczanie wyrażenia jest opóźnione do momentu, aż jego zrealizowana wartość zostanie iterowana lub ToListAsync
wywołana metoda. Aby uzyskać więcej informacji, zobacz Wykonywanie zapytań.
Uwaga
Metoda Contains jest uruchamiana w bazie danych, a nie w kodzie języka C#. Ważność wielkości liter w zapytaniu zależy od bazy danych i sortowania. W programie SQL Server Contains
mapuje na sql LIKE, co jest bez uwzględniania wielkości liter. SqLite z sortowaniem domyślnym jest kombinacją wielkości liter i wielkości liter w rozróżnianiu w zależności od zapytania. Aby uzyskać informacje na temat tworzenia zapytań SQLite bez uwzględniania wielkości liter, zobacz następujące kwestie:
Przejdź do strony Filmy i dołącz ciąg zapytania, taki jak ?searchString=Ghost
adres URL. Na przykład https://localhost:5001/Movies?searchString=Ghost
. Zostaną wyświetlone przefiltrowane filmy.
Jeśli następujący szablon trasy zostanie dodany do strony Indeks, ciąg wyszukiwania można przekazać jako segment adresu URL. Na przykład https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
Powyższe ograniczenie trasy umożliwia przeszukiwanie tytułu jako danych trasy (segment adresu URL) zamiast jako wartości ciągu zapytania. Wartość ?
in "{searchString?}"
oznacza, że jest to opcjonalny parametr trasy.
Środowisko uruchomieniowe ASP.NET Core używa powiązania modelu, aby ustawić wartość SearchString
właściwości z ciągu zapytania (?searchString=Ghost
) lub danych trasy (https://localhost:5001/Movies/Ghost
). Powiązanie modelu nie uwzględnia wielkości liter.
Nie można jednak oczekiwać zmodyfikowania adresu URL w celu wyszukania filmu. W tym kroku interfejs użytkownika jest dodawany do filtrowania filmów. Jeśli dodano ograniczenie "{searchString?}"
trasy, usuń go.
Pages/Movies/Index.cshtml
Otwórz plik i dodaj znacznik wyróżniony w następującym kodzie:
@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.*@
Tag HTML <form>
używa następujących pomocników tagów:
- Pomocnik tagu formularza. Po przesłaniu formularza ciąg filtru jest wysyłany do strony Pages/Movies/Index za pośrednictwem ciągu zapytania.
- Pomocnik tagów danych wejściowych
Zapisz zmiany i przetestuj filtr.
Wyszukiwanie według gatunku
Zaktualizuj metodę strony indeksu OnGetAsync
przy użyciu następującego kodu:
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();
}
Poniższy kod to zapytanie LINQ, które pobiera wszystkie gatunki z bazy danych.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
Gatunek SelectList
jest tworzony przez projekcję odrębnych gatunków.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Dodawanie wyszukiwania według gatunku Razor do strony
Index.cshtml
<form>
Zaktualizuj element jako wyróżniony w następującym znaczniku:
@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>
Przetestuj aplikację, wyszukując według gatunku, według tytułu filmu i obu.
Następne kroki
W poniższych sekcjach dodano wyszukiwanie filmów według gatunku lub nazwy .
Dodaj następujący wyróżniony kod do :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; }
W poprzednim kodzie:
SearchString
: zawiera tekst, który użytkownicy wprowadzają w polu tekstowym wyszukiwania.SearchString
[BindProperty]
ma atrybut .[BindProperty]
Wiąże wartości formularza i ciągi zapytania o taką samą nazwę jak właściwość.[BindProperty(SupportsGet = true)]
jest wymagany do wiązania żądań HTTP GET.Genres
: zawiera listę gatunków.Genres
umożliwia użytkownikowi wybranie gatunku z listy.SelectList
Wymagausing Microsoft.AspNetCore.Mvc.Rendering;
MovieGenre
: zawiera określony gatunek wybierany przez użytkownika. Na przykład "Western".Genres
iMovieGenre
są używane w dalszej części tego samouczka.
Ostrzeżenie
Ze względów bezpieczeństwa należy wyrazić zgodę na powiązanie danych żądania GET
z właściwościami modelu strony. Przed mapowaniem danych wejściowych użytkownika na właściwości zweryfikuj je. Wyrażenie zgody na powiązanie danych GET
jest przydatne w scenariuszach, które wykorzystują ciągi zapytania lub wartości trasy.
Aby powiązać właściwość w przypadku żądań GET
, ustaw właściwość SupportsGet
atrybutu [BindProperty]
na true
:
[BindProperty(SupportsGet = true)]
Aby uzyskać więcej informacji, zobacz Podsumowanie ASP.NET Core Community Standup: dyskusja na temat powiązania z użyciem metody GET (YouTube).
Zaktualizuj metodę strony indeksu OnGetAsync
przy użyciu następującego kodu:
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();
}
Pierwszy wiersz OnGetAsync
metody tworzy zapytanie LINQ w celu wybrania filmów:
// using System.Linq;
var movies = from m in _context.Movie
select m;
Zapytanie jest zdefiniowane tylko w tym momencie, nie zostało ono uruchomione względem bazy danych.
SearchString
Jeśli właściwość nie ma wartości null lub jest pusta, zapytanie filmów jest modyfikowane w celu filtrowania w ciągu wyszukiwania:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Kod s => s.Title.Contains()
jest wyrażeniem lambda. Wyrażenia lambda są używane w zapytaniach LINQ opartych na metodzie jako argumentach do standardowych metod operatorów zapytań, takich jak metoda Where lub Contains
. Zapytania LINQ nie są wykonywane podczas ich definiowania lub modyfikacji przez wywołanie metody, takiej jak Where
, Contains
lub OrderBy
. Zamiast tego wykonywanie zapytań jest odroczone. Obliczanie wyrażenia jest opóźnione do momentu, aż jego zrealizowana wartość zostanie iterowana lub ToListAsync
wywołana metoda. Aby uzyskać więcej informacji, zobacz Wykonywanie zapytań.
Uwaga
Metoda Contains jest uruchamiana w bazie danych, a nie w kodzie języka C#. Ważność wielkości liter w zapytaniu zależy od bazy danych i sortowania. W programie SQL Server Contains
mapuje na sql LIKE, co jest bez uwzględniania wielkości liter. SqLite z sortowaniem domyślnym jest kombinacją wielkości liter i wielkości liter w rozróżnianiu w zależności od zapytania. Aby uzyskać informacje na temat tworzenia zapytań SQLite bez uwzględniania wielkości liter, zobacz następujące kwestie:
Przejdź do strony Filmy i dołącz ciąg zapytania, taki jak ?searchString=Ghost
adres URL. Na przykład https://localhost:5001/Movies?searchString=Ghost
. Zostaną wyświetlone przefiltrowane filmy.
Jeśli następujący szablon trasy zostanie dodany do strony Indeks, ciąg wyszukiwania można przekazać jako segment adresu URL. Na przykład https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
Powyższe ograniczenie trasy umożliwia przeszukiwanie tytułu jako danych trasy (segment adresu URL) zamiast jako wartości ciągu zapytania. Wartość ?
in "{searchString?}"
oznacza, że jest to opcjonalny parametr trasy.
Środowisko uruchomieniowe ASP.NET Core używa powiązania modelu, aby ustawić wartość SearchString
właściwości z ciągu zapytania (?searchString=Ghost
) lub danych trasy (https://localhost:5001/Movies/Ghost
). Powiązanie modelu nie uwzględnia wielkości liter.
Nie można jednak oczekiwać zmodyfikowania adresu URL w celu wyszukania filmu. W tym kroku interfejs użytkownika jest dodawany do filtrowania filmów. Jeśli dodano ograniczenie "{searchString?}"
trasy, usuń go.
Pages/Movies/Index.cshtml
Otwórz plik i dodaj znacznik wyróżniony w następującym kodzie:
@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.*@
Tag HTML <form>
używa następujących pomocników tagów:
- Pomocnik tagu formularza. Po przesłaniu formularza ciąg filtru jest wysyłany do strony Pages/Movies/Index za pośrednictwem ciągu zapytania.
- Pomocnik tagów danych wejściowych
Zapisz zmiany i przetestuj filtr.
Wyszukiwanie według gatunku
Zaktualizuj metodę strony indeksu OnGetAsync
przy użyciu następującego kodu:
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();
}
Poniższy kod to zapytanie LINQ, które pobiera wszystkie gatunki z bazy danych.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
Gatunek SelectList
jest tworzony przez projekcję odrębnych gatunków.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Dodawanie wyszukiwania według gatunku Razor do strony
Index.cshtml
<form>
Zaktualizuj element jako wyróżniony w następującym znaczniku:
@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>
Przetestuj aplikację, wyszukując według gatunku, według tytułu filmu i obu.
Następne kroki
W poniższych sekcjach dodano wyszukiwanie filmów według gatunku lub nazwy .
Dodaj następujące wyróżnione polecenie przy użyciu instrukcji i właściwości do polecenia 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; }
W poprzednim kodzie:
SearchString
: zawiera tekst, który użytkownicy wprowadzają w polu tekstowym wyszukiwania.SearchString
[BindProperty]
ma atrybut .[BindProperty]
Wiąże wartości formularza i ciągi zapytania o taką samą nazwę jak właściwość.[BindProperty(SupportsGet = true)]
jest wymagany do wiązania żądań HTTP GET.Genres
: zawiera listę gatunków.Genres
umożliwia użytkownikowi wybranie gatunku z listy.SelectList
Wymagausing Microsoft.AspNetCore.Mvc.Rendering;
MovieGenre
: zawiera określony gatunek wybierany przez użytkownika. Na przykład "Western".Genres
iMovieGenre
są używane w dalszej części tego samouczka.
Ostrzeżenie
Ze względów bezpieczeństwa należy wyrazić zgodę na powiązanie danych żądania GET
z właściwościami modelu strony. Przed mapowaniem danych wejściowych użytkownika na właściwości zweryfikuj je. Wyrażenie zgody na powiązanie danych GET
jest przydatne w scenariuszach, które wykorzystują ciągi zapytania lub wartości trasy.
Aby powiązać właściwość w przypadku żądań GET
, ustaw właściwość SupportsGet
atrybutu [BindProperty]
na true
:
[BindProperty(SupportsGet = true)]
Aby uzyskać więcej informacji, zobacz Podsumowanie ASP.NET Core Community Standup: dyskusja na temat powiązania z użyciem metody GET (YouTube).
Zaktualizuj metodę strony indeksu OnGetAsync
przy użyciu następującego kodu:
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();
}
Pierwszy wiersz OnGetAsync
metody tworzy zapytanie LINQ w celu wybrania filmów:
// using System.Linq;
var movies = from m in _context.Movie
select m;
Zapytanie jest zdefiniowane tylko w tym momencie, nie zostało ono uruchomione względem bazy danych.
SearchString
Jeśli właściwość nie ma wartości null lub jest pusta, zapytanie filmów jest modyfikowane w celu filtrowania w ciągu wyszukiwania:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Kod s => s.Title.Contains()
jest wyrażeniem lambda. Wyrażenia lambda są używane w zapytaniach LINQ opartych na metodzie jako argumentach do standardowych metod operatorów zapytań, takich jak metoda Where lub Contains
. Zapytania LINQ nie są wykonywane podczas ich definiowania lub modyfikacji przez wywołanie metody, takiej jak Where
, Contains
lub OrderBy
. Zamiast tego wykonywanie zapytań jest odroczone. Obliczanie wyrażenia jest opóźnione do momentu, aż jego zrealizowana wartość zostanie iterowana lub ToListAsync
wywołana metoda. Aby uzyskać więcej informacji, zobacz Wykonywanie zapytań.
Uwaga
Metoda Contains jest uruchamiana w bazie danych, a nie w kodzie języka C#. Ważność wielkości liter w zapytaniu zależy od bazy danych i sortowania. W programie SQL Server Contains
mapuje na sql LIKE, co jest bez uwzględniania wielkości liter. SqLite z sortowaniem domyślnym jest kombinacją wielkości liter i wielkości liter w rozróżnianiu w zależności od zapytania. Aby uzyskać informacje na temat tworzenia zapytań SQLite bez uwzględniania wielkości liter, zobacz następujące kwestie:
Przejdź do strony Filmy i dołącz ciąg zapytania, taki jak ?searchString=Ghost
adres URL. Na przykład https://localhost:5001/Movies?searchString=Ghost
. Zostaną wyświetlone przefiltrowane filmy.
Jeśli następujący szablon trasy zostanie dodany do strony Indeks, ciąg wyszukiwania można przekazać jako segment adresu URL. Na przykład https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
Powyższe ograniczenie trasy umożliwia przeszukiwanie tytułu jako danych trasy (segment adresu URL) zamiast jako wartości ciągu zapytania. Wartość ?
in "{searchString?}"
oznacza, że jest to opcjonalny parametr trasy.
Środowisko uruchomieniowe ASP.NET Core używa powiązania modelu, aby ustawić wartość SearchString
właściwości z ciągu zapytania (?searchString=Ghost
) lub danych trasy (https://localhost:5001/Movies/Ghost
). Powiązanie modelu nie uwzględnia wielkości liter.
Nie można jednak oczekiwać zmodyfikowania adresu URL w celu wyszukania filmu. W tym kroku interfejs użytkownika jest dodawany do filtrowania filmów. Jeśli dodano ograniczenie "{searchString?}"
trasy, usuń go.
Pages/Movies/Index.cshtml
Otwórz plik i dodaj znacznik wyróżniony w następującym kodzie:
@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.*@
Tag HTML <form>
używa następujących pomocników tagów:
- Pomocnik tagu formularza. Po przesłaniu formularza ciąg filtru jest wysyłany do strony Pages/Movies/Index za pośrednictwem ciągu zapytania.
- Pomocnik tagów danych wejściowych
Zapisz zmiany i przetestuj filtr.
Wyszukiwanie według gatunku
Zaktualizuj metodę strony indeksu OnGetAsync
przy użyciu następującego kodu:
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();
}
Poniższy kod to zapytanie LINQ, które pobiera wszystkie gatunki z bazy danych.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
Gatunek SelectList
jest tworzony przez projekcję odrębnych gatunków.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Dodawanie wyszukiwania według gatunku Razor do strony
Index.cshtml
<form>
Zaktualizuj element jako wyróżniony w następującym znaczniku:@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.*@
Przetestuj aplikację, wyszukując według gatunku, według tytułu filmu i obu.