Teil 6: Hinzufügen der Suche zu Razor Pages in ASP.NET Core
Hinweis
Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.
Warnung
Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der .NET- und .NET Core-Supportrichtlinie. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.
Wichtig
Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.
Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.
Von Rick Anderson
In den folgenden Abschnitten wird eine Suche nach Filmen anhand von Genre oder Name hinzugefügt.
Fügen Sie folgenden hervorgehobenen Code zu Pages/Movies/Index.cshtml.cs
hinzu:
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; }
Im vorherigen Code:
SearchString
: Enthält den Text, den Benutzer in das Suchtextfeld eingeben.SearchString
weist das Attribut[BindProperty]
auf.[BindProperty]
bindet Formularwerte und Abfragezeichenfolgen mit dem gleichen Namen wie die Eigenschaft.[BindProperty(SupportsGet = true)]
ist für die Bindung in HTTP GET-Anforderungen erforderlich.Genres
: Enthält die Liste der Genres.Genres
ermöglicht es dem Benutzer, ein Genre in der Liste auszuwählen.SelectList
erfordertusing Microsoft.AspNetCore.Mvc.Rendering;
.MovieGenre
: Enthält das spezifische vom Benutzer auswählte Genre. Beispiel: Western.Genres
undMovieGenre
werden später in diesem Tutorial verwendet.
Warnung
Aus Sicherheitsgründen müssen Sie Daten von GET
-Anforderungen in die Seitenmodelleigenschaften einbinden. Überprüfen Sie die Benutzereingaben, bevor Sie sie den Eigenschaften zuordnen. Die Verwendung der GET
-Bindung ist von Vorteil, wenn Sie Szenarios behandeln, die von Abfragezeichenfolgen oder Routenwerten abhängig sind.
Legen Sie die SupportsGet
-Eigenschaft des [BindProperty]
-Attributs auf true
fest, um eine Eigenschaft an GET
-Anforderungen zu binden:
[BindProperty(SupportsGet = true)]
Weitere Informationen finden Sie unter ASP.NET Core Community Standup: Binden auf GET-Diskussion (YouTube).
Aktualisieren Sie die OnGetAsync
-Methode der Seite Movies/Index
mit folgendem Code:
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();
}
Die erste Zeile der OnGetAsync
-Methode erstellt eine LINQ-Abfrage zum Auswählen der Filme:
var movies = from m in _context.Movie
select m;
Die Abfrage wird an diesem Punkt nur definiert. Sie wurde noch nicht auf die Datenbank angewendet.
Wenn die SearchString
-Eigenschaft nicht null
oder leer ist, wird die Abfrage nach Filmen so geändert, dass die Suchzeichenfolge gefiltert wird:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Der Code s => s.Title.Contains()
ist ein Lambdaausdruck. Lambdaausdrücke werden in methodenbasierten LINQ-Abfragen als Argumente für standardmäßige Abfrageoperatormethoden wie die Where-Methode oder Contains
verwendet. LINQ-Abfragen werden nicht ausgeführt, wenn sie definiert oder durch Aufrufen einer Methode wie z. B. Where
, Contains
oder OrderBy
geändert werden. Stattdessen wird die Ausführung der Abfrage verzögert. Die Auswertung eines Ausdrucks wird so lange hinausgezögert, bis dessen realisierter Wert durchlaufen oder die ToListAsync
-Methode aufgerufen wird. Weitere Informationen finden Sie unter Abfrageausführung.
Hinweis
Die Contains-Methode wird in der Datenbank und nicht im C#-Code ausgeführt. Die Groß-/Kleinschreibung in der Abfrage hängt von der Datenbank und Sortierung ab. In SQL Server wird Contains
zu SQL LIKE zugeordnet, das Groß-/Kleinschreibung nicht beachtet. In SQLite mit der Standardsortierung wird die Groß-/Kleinschreibung abhängig von der Abfrage berücksichtigt oder NICHT berücksichtigt. Informationen dazu, wie Sie SQLite-Abfragen ohne Unterscheidung der Groß-/Kleinschreibung stellen, finden Sie in den folgenden Themen:
Navigieren Sie zur Seite „Movies“, und fügen Sie eine Abfragezeichenfolge wie z. B. ?searchString=Ghost
an die URL an. Beispiel: https://localhost:5001/Movies?searchString=Ghost
. Die gefilterten Filme werden angezeigt.
Wenn die Routenvorlage der Indexseite hinzugefügt wird, kann die Suchzeichenfolge als URL-Segment übergeben werden. Beispiel: https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
Die vorangehende Routeneinschränkung ermöglicht das Suchen des Titels als Routendaten (URL-Segment) anstatt als Wert einer Abfragezeichenfolge. Das ?
in "{searchString?}"
bedeutet, dass dies ein optionaler Routenparameter ist.
Die ASP.NET Core-Runtime verwendet die Modellbindung, um den Wert der SearchString
-Eigenschaft aus der Abfragezeichenfolge (?searchString=Ghost
) oder aus Datenrouten (https://localhost:5001/Movies/Ghost
) festzulegen. Bei der Modellbindung wird Groß- und Kleinschreibung nicht berücksichtigt.
Sie können jedoch von Benutzern nicht erwarten, dass sie die URL ändern, um nach einem Film zu suchen. In diesem Schritt wird eine Benutzeroberflächenoption hinzugefügt, um Filme zu filtern. Wenn Sie die Routeneinschränkung "{searchString?}"
hinzugefügt haben, entfernen Sie sie.
Öffnen Sie die Datei Pages/Movies/Index.cshtml
, und fügen Sie im folgenden Code das hervorgehobene Markup hinzu:
@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>
Das HTML-Tag <form>
verwendet die folgenden Taghilfsprogramme:
- Hilfsprogramm für Formulartags. Bei der Übermittlung des Formulars wird die Filterzeichenfolge über die Abfragezeichenfolge an die Seite Pages/Movies/Index gesendet.
- Hilfsprogramm für Eingabetags
Speichern Sie die Änderungen, und testen Sie den Filter.
Suche nach Genre
Aktualisieren Sie die OnGetAsync
-Methode der Seite Movies/Index.cshtml.cs
mit folgendem Code:
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();
}
Der folgende Code ist eine LINQ-Abfrage, die alle Genres aus der Datenbank abruft.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
SelectList
von Genres wird durch Projizieren der unterschiedlichen Genres erstellt:
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Hinzufügen einer Suche anhand von Genre zur Razor Page
Aktualisieren Sie das Index.cshtml
<form>
-Element wie im folgenden Markup hervorgehoben:
@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>
Testen Sie die App mit einer Suche nach Genre, Filmtitel und beidem:
Nächste Schritte
In den folgenden Abschnitten wird eine Suche nach Filmen anhand von Genre oder Name hinzugefügt.
Fügen Sie folgenden hervorgehobenen Code zu Pages/Movies/Index.cshtml.cs
hinzu:
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; }
Im vorherigen Code:
SearchString
: Enthält den Text, den Benutzer in das Suchtextfeld eingeben.SearchString
weist das Attribut[BindProperty]
auf.[BindProperty]
bindet Formularwerte und Abfragezeichenfolgen mit dem gleichen Namen wie die Eigenschaft.[BindProperty(SupportsGet = true)]
ist für die Bindung in HTTP GET-Anforderungen erforderlich.Genres
: Enthält die Liste der Genres.Genres
ermöglicht es dem Benutzer, ein Genre in der Liste auszuwählen.SelectList
erfordertusing Microsoft.AspNetCore.Mvc.Rendering;
.MovieGenre
: Enthält das spezifische vom Benutzer auswählte Genre. Beispiel: Western.Genres
undMovieGenre
werden später in diesem Tutorial verwendet.
Warnung
Aus Sicherheitsgründen müssen Sie Daten von GET
-Anforderungen in die Seitenmodelleigenschaften einbinden. Überprüfen Sie die Benutzereingaben, bevor Sie sie den Eigenschaften zuordnen. Die Verwendung der GET
-Bindung ist von Vorteil, wenn Sie Szenarios behandeln, die von Abfragezeichenfolgen oder Routenwerten abhängig sind.
Legen Sie die SupportsGet
-Eigenschaft des [BindProperty]
-Attributs auf true
fest, um eine Eigenschaft an GET
-Anforderungen zu binden:
[BindProperty(SupportsGet = true)]
Weitere Informationen finden Sie unter ASP.NET Core Community Standup: Binden auf GET-Diskussion (YouTube).
Aktualisieren Sie die OnGetAsync
-Methode der Indexseite mit folgendem Code:
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();
}
Die erste Zeile der OnGetAsync
-Methode erstellt eine LINQ-Abfrage zum Auswählen der Filme:
// using System.Linq;
var movies = from m in _context.Movie
select m;
Die Abfrage wird an diesem Punkt nur definiert. Sie wurde noch nicht auf die Datenbank angewendet.
Wenn die SearchString
-Eigenschaft nicht null
oder leer ist, wird die Abfrage nach Filmen so geändert, dass die Suchzeichenfolge gefiltert wird:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Der Code s => s.Title.Contains()
ist ein Lambdaausdruck. Lambdaausdrücke werden in methodenbasierten LINQ-Abfragen als Argumente für standardmäßige Abfrageoperatormethoden wie die Where-Methode oder Contains
verwendet. LINQ-Abfragen werden nicht ausgeführt, wenn sie definiert oder durch Aufrufen einer Methode wie z. B. Where
, Contains
oder OrderBy
geändert werden. Stattdessen wird die Ausführung der Abfrage verzögert. Die Auswertung eines Ausdrucks wird so lange hinausgezögert, bis dessen realisierter Wert durchlaufen oder die ToListAsync
-Methode aufgerufen wird. Weitere Informationen finden Sie unter Abfrageausführung.
Hinweis
Die Contains-Methode wird in der Datenbank und nicht im C#-Code ausgeführt. Die Groß-/Kleinschreibung in der Abfrage hängt von der Datenbank und Sortierung ab. In SQL Server wird Contains
zu SQL LIKE zugeordnet, das Groß-/Kleinschreibung nicht beachtet. In SQLite mit der Standardsortierung wird die Groß-/Kleinschreibung abhängig von der Abfrage berücksichtigt oder NICHT berücksichtigt. Informationen dazu, wie Sie SQLite-Abfragen ohne Unterscheidung der Groß-/Kleinschreibung stellen, finden Sie in den folgenden Themen:
Navigieren Sie zur Seite „Movies“, und fügen Sie eine Abfragezeichenfolge wie z. B. ?searchString=Ghost
an die URL an. Beispiel: https://localhost:5001/Movies?searchString=Ghost
. Die gefilterten Filme werden angezeigt.
Wenn die Routenvorlage der Indexseite hinzugefügt wird, kann die Suchzeichenfolge als URL-Segment übergeben werden. Beispiel: https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
Die vorangehende Routeneinschränkung ermöglicht das Suchen des Titels als Routendaten (URL-Segment) anstatt als Wert einer Abfragezeichenfolge. Das ?
in "{searchString?}"
bedeutet, dass dies ein optionaler Routenparameter ist.
Die ASP.NET Core-Runtime verwendet die Modellbindung, um den Wert der SearchString
-Eigenschaft aus der Abfragezeichenfolge (?searchString=Ghost
) oder aus Datenrouten (https://localhost:5001/Movies/Ghost
) festzulegen. Bei der Modellbindung wird Groß- und Kleinschreibung nicht berücksichtigt.
Sie können jedoch von Benutzern nicht erwarten, dass sie die URL ändern, um nach einem Film zu suchen. In diesem Schritt wird eine Benutzeroberflächenoption hinzugefügt, um Filme zu filtern. Wenn Sie die Routeneinschränkung "{searchString?}"
hinzugefügt haben, entfernen Sie sie.
Öffnen Sie die Datei Pages/Movies/Index.cshtml
, und fügen Sie im folgenden Code das hervorgehobene Markup hinzu:
@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.*@
Das HTML-Tag <form>
verwendet die folgenden Taghilfsprogramme:
- Hilfsprogramm für Formulartags. Bei der Übermittlung des Formulars wird die Filterzeichenfolge über die Abfragezeichenfolge an die Seite Pages/Movies/Index gesendet.
- Hilfsprogramm für Eingabetags
Speichern Sie die Änderungen, und testen Sie den Filter.
Suche nach Genre
Aktualisieren Sie die OnGetAsync
-Methode der Seite Movies/Index.cshtml.cs
mit folgendem Code:
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();
}
Der folgende Code ist eine LINQ-Abfrage, die alle Genres aus der Datenbank abruft.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
Die SelectList
von Genres wird durch Projizieren der unterschiedlichen Genres erstellt.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Hinzufügen einer Suche anhand von Genre zur Razor Page
Aktualisieren Sie das Index.cshtml
<form>
-Element wie im folgenden Markup hervorgehoben:
@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>
Testen Sie die App mit einer Suche nach Genre, Filmtitel und beidem.
Nächste Schritte
In den folgenden Abschnitten wird eine Suche nach Filmen anhand von Genre oder Name hinzugefügt.
Fügen Sie folgenden hervorgehobenen Code zu Pages/Movies/Index.cshtml.cs
hinzu:
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; }
Im vorherigen Code:
SearchString
: Enthält den Text, den Benutzer in das Suchtextfeld eingeben.SearchString
weist das Attribut[BindProperty]
auf.[BindProperty]
bindet Formularwerte und Abfragezeichenfolgen mit dem gleichen Namen wie die Eigenschaft.[BindProperty(SupportsGet = true)]
ist für die Bindung in HTTP GET-Anforderungen erforderlich.Genres
: Enthält die Liste der Genres.Genres
ermöglicht es dem Benutzer, ein Genre in der Liste auszuwählen.SelectList
erfordertusing Microsoft.AspNetCore.Mvc.Rendering;
.MovieGenre
: Enthält das spezifische vom Benutzer auswählte Genre. Beispiel: Western.Genres
undMovieGenre
werden später in diesem Tutorial verwendet.
Warnung
Aus Sicherheitsgründen müssen Sie Daten von GET
-Anforderungen in die Seitenmodelleigenschaften einbinden. Überprüfen Sie die Benutzereingaben, bevor Sie sie den Eigenschaften zuordnen. Die Verwendung der GET
-Bindung ist von Vorteil, wenn Sie Szenarios behandeln, die von Abfragezeichenfolgen oder Routenwerten abhängig sind.
Legen Sie die SupportsGet
-Eigenschaft des [BindProperty]
-Attributs auf true
fest, um eine Eigenschaft an GET
-Anforderungen zu binden:
[BindProperty(SupportsGet = true)]
Weitere Informationen finden Sie unter ASP.NET Core Community Standup: Binden auf GET-Diskussion (YouTube).
Aktualisieren Sie die OnGetAsync
-Methode der Indexseite mit folgendem Code:
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();
}
Die erste Zeile der OnGetAsync
-Methode erstellt eine LINQ-Abfrage zum Auswählen der Filme:
// using System.Linq;
var movies = from m in _context.Movie
select m;
Die Abfrage wird an diesem Punkt nur definiert. Sie wurde noch nicht auf die Datenbank angewendet.
Wenn die SearchString
-Eigenschaft nicht null
oder leer ist, wird die Abfrage nach Filmen so geändert, dass die Suchzeichenfolge gefiltert wird:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Der Code s => s.Title.Contains()
ist ein Lambdaausdruck. Lambdaausdrücke werden in methodenbasierten LINQ-Abfragen als Argumente für standardmäßige Abfrageoperatormethoden wie die Where-Methode oder Contains
verwendet. LINQ-Abfragen werden nicht ausgeführt, wenn sie definiert oder durch Aufrufen einer Methode wie z. B. Where
, Contains
oder OrderBy
geändert werden. Stattdessen wird die Ausführung der Abfrage verzögert. Die Auswertung eines Ausdrucks wird so lange hinausgezögert, bis dessen realisierter Wert durchlaufen oder die ToListAsync
-Methode aufgerufen wird. Weitere Informationen finden Sie unter Abfrageausführung.
Hinweis
Die Contains-Methode wird in der Datenbank und nicht im C#-Code ausgeführt. Die Groß-/Kleinschreibung in der Abfrage hängt von der Datenbank und Sortierung ab. In SQL Server wird Contains
zu SQL LIKE zugeordnet, das Groß-/Kleinschreibung nicht beachtet. In SQLite mit der Standardsortierung wird die Groß-/Kleinschreibung abhängig von der Abfrage berücksichtigt oder NICHT berücksichtigt. Informationen dazu, wie Sie SQLite-Abfragen ohne Unterscheidung der Groß-/Kleinschreibung stellen, finden Sie in den folgenden Themen:
- Dieses GitHub-Issue.
- Dieses GitHub-Issue.
- Sortierungen und Unterscheidung nach Groß-/Kleinschreibung
Navigieren Sie zur Seite „Movies“, und fügen Sie eine Abfragezeichenfolge wie z. B. ?searchString=Ghost
an die URL an. Beispiel: https://localhost:5001/Movies?searchString=Ghost
. Die gefilterten Filme werden angezeigt.
Wenn die Routenvorlage der Indexseite hinzugefügt wird, kann die Suchzeichenfolge als URL-Segment übergeben werden. Beispiel: https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
Die vorangehende Routeneinschränkung ermöglicht das Suchen des Titels als Routendaten (URL-Segment) anstatt als Wert einer Abfragezeichenfolge. Das ?
in "{searchString?}"
bedeutet, dass dies ein optionaler Routenparameter ist.
Die ASP.NET Core-Runtime verwendet die Modellbindung, um den Wert der SearchString
-Eigenschaft aus der Abfragezeichenfolge (?searchString=Ghost
) oder aus Datenrouten (https://localhost:5001/Movies/Ghost
) festzulegen. Bei der Modellbindung wird Groß- und Kleinschreibung nicht berücksichtigt.
Sie können jedoch von Benutzern nicht erwarten, dass sie die URL ändern, um nach einem Film zu suchen. In diesem Schritt wird eine Benutzeroberflächenoption hinzugefügt, um Filme zu filtern. Wenn Sie die Routeneinschränkung "{searchString?}"
hinzugefügt haben, entfernen Sie sie.
Öffnen Sie die Datei Pages/Movies/Index.cshtml
, und fügen Sie im folgenden Code das hervorgehobene Markup hinzu:
@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.*@
Das HTML-Tag <form>
verwendet die folgenden Taghilfsprogramme:
- Hilfsprogramm für Formulartags. Bei der Übermittlung des Formulars wird die Filterzeichenfolge über die Abfragezeichenfolge an die Seite Pages/Movies/Index gesendet.
- Hilfsprogramm für Eingabetags
Speichern Sie die Änderungen, und testen Sie den Filter.
Suche nach Genre
Aktualisieren Sie die OnGetAsync
-Methode der Indexseite mit folgendem Code:
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();
}
Der folgende Code ist eine LINQ-Abfrage, die alle Genres aus der Datenbank abruft.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
Die SelectList
von Genres wird durch Projizieren der unterschiedlichen Genres erstellt.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Hinzufügen einer Suche anhand von Genre zur Razor Page
Aktualisieren Sie das Index.cshtml
<form>
-Element wie im folgenden Markup hervorgehoben:
@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>
Testen Sie die App mit einer Suche nach Genre, Filmtitel und beidem.
Nächste Schritte
In den folgenden Abschnitten wird eine Suche nach Filmen anhand von Genre oder Name hinzugefügt.
Fügen Sie folgenden hervorgehobenen Code zu Pages/Movies/Index.cshtml.cs
hinzu:
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; }
Im vorherigen Code:
SearchString
: Enthält den Text, den Benutzer in das Suchtextfeld eingeben.SearchString
weist das Attribut[BindProperty]
auf.[BindProperty]
bindet Formularwerte und Abfragezeichenfolgen mit dem gleichen Namen wie die Eigenschaft.[BindProperty(SupportsGet = true)]
ist für die Bindung in HTTP GET-Anforderungen erforderlich.Genres
: Enthält die Liste der Genres.Genres
ermöglicht es dem Benutzer, ein Genre in der Liste auszuwählen.SelectList
erfordertusing Microsoft.AspNetCore.Mvc.Rendering;
.MovieGenre
: Enthält das spezifische vom Benutzer auswählte Genre. Beispiel: Western.Genres
undMovieGenre
werden später in diesem Tutorial verwendet.
Warnung
Aus Sicherheitsgründen müssen Sie Daten von GET
-Anforderungen in die Seitenmodelleigenschaften einbinden. Überprüfen Sie die Benutzereingaben, bevor Sie sie den Eigenschaften zuordnen. Die Verwendung der GET
-Bindung ist von Vorteil, wenn Sie Szenarios behandeln, die von Abfragezeichenfolgen oder Routenwerten abhängig sind.
Legen Sie die SupportsGet
-Eigenschaft des [BindProperty]
-Attributs auf true
fest, um eine Eigenschaft an GET
-Anforderungen zu binden:
[BindProperty(SupportsGet = true)]
Weitere Informationen finden Sie unter ASP.NET Core Community Standup: Binden auf GET-Diskussion (YouTube).
Aktualisieren Sie die OnGetAsync
-Methode der Indexseite mit folgendem Code:
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();
}
Die erste Zeile der OnGetAsync
-Methode erstellt eine LINQ-Abfrage zum Auswählen der Filme:
// using System.Linq;
var movies = from m in _context.Movie
select m;
Die Abfrage wird an diesem Punkt nur definiert. Sie wurde noch nicht auf die Datenbank angewendet.
Wenn die SearchString
-Eigenschaft nicht NULL oder leer ist, wird die Abfrage nach Filmen so geändert, dass die Suchzeichenfolge gefiltert wird:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Der Code s => s.Title.Contains()
ist ein Lambdaausdruck. Lambdaausdrücke werden in methodenbasierten LINQ-Abfragen als Argumente für standardmäßige Abfrageoperatormethoden wie die Where-Methode oder Contains
verwendet. LINQ-Abfragen werden nicht ausgeführt, wenn sie definiert oder durch Aufrufen einer Methode wie z. B. Where
, Contains
oder OrderBy
geändert werden. Stattdessen wird die Ausführung der Abfrage verzögert. Die Auswertung eines Ausdrucks wird so lange hinausgezögert, bis dessen realisierter Wert durchlaufen oder die ToListAsync
-Methode aufgerufen wird. Weitere Informationen finden Sie unter Abfrageausführung.
Hinweis
Die Contains-Methode wird in der Datenbank und nicht im C#-Code ausgeführt. Die Groß-/Kleinschreibung in der Abfrage hängt von der Datenbank und Sortierung ab. In SQL Server wird Contains
zu SQL LIKE zugeordnet, das Groß-/Kleinschreibung nicht beachtet. In SQLite mit der Standardsortierung wird die Groß-/Kleinschreibung abhängig von der Abfrage berücksichtigt oder NICHT berücksichtigt. Informationen dazu, wie Sie SQLite-Abfragen ohne Unterscheidung der Groß-/Kleinschreibung stellen, finden Sie in den folgenden Themen:
- Dieses GitHub-Issue.
- Dieses GitHub-Issue.
- Sortierungen und Unterscheidung nach Groß-/Kleinschreibung
Navigieren Sie zur Seite „Movies“, und fügen Sie eine Abfragezeichenfolge wie z. B. ?searchString=Ghost
an die URL an. Beispiel: https://localhost:5001/Movies?searchString=Ghost
. Die gefilterten Filme werden angezeigt.
Wenn die Routenvorlage der Indexseite hinzugefügt wird, kann die Suchzeichenfolge als URL-Segment übergeben werden. Beispiel: https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
Die vorangehende Routeneinschränkung ermöglicht das Suchen des Titels als Routendaten (URL-Segment) anstatt als Wert einer Abfragezeichenfolge. Das ?
in "{searchString?}"
bedeutet, dass dies ein optionaler Routenparameter ist.
Die ASP.NET Core-Runtime verwendet die Modellbindung, um den Wert der SearchString
-Eigenschaft aus der Abfragezeichenfolge (?searchString=Ghost
) oder aus Datenrouten (https://localhost:5001/Movies/Ghost
) festzulegen. Bei der Modellbindung wird Groß- und Kleinschreibung nicht berücksichtigt.
Sie können jedoch von Benutzern nicht erwarten, dass sie die URL ändern, um nach einem Film zu suchen. In diesem Schritt wird eine Benutzeroberflächenoption hinzugefügt, um Filme zu filtern. Wenn Sie die Routeneinschränkung "{searchString?}"
hinzugefügt haben, entfernen Sie sie.
Öffnen Sie die Datei Pages/Movies/Index.cshtml
, und fügen Sie im folgenden Code das hervorgehobene Markup hinzu:
@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.*@
Das HTML-Tag <form>
verwendet die folgenden Taghilfsprogramme:
- Hilfsprogramm für Formulartags. Bei der Übermittlung des Formulars wird die Filterzeichenfolge über die Abfragezeichenfolge an die Seite Pages/Movies/Index gesendet.
- Hilfsprogramm für Eingabetags
Speichern Sie die Änderungen, und testen Sie den Filter.
Suche nach Genre
Aktualisieren Sie die OnGetAsync
-Methode der Indexseite mit folgendem Code:
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();
}
Der folgende Code ist eine LINQ-Abfrage, die alle Genres aus der Datenbank abruft.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
Die SelectList
von Genres wird durch Projizieren der unterschiedlichen Genres erstellt.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Hinzufügen einer Suche anhand von Genre zur Razor Page
Aktualisieren Sie das Index.cshtml
<form>
-Element wie im folgenden Markup hervorgehoben:
@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>
Testen Sie die App mit einer Suche nach Genre, Filmtitel und beidem.
Nächste Schritte
In den folgenden Abschnitten wird eine Suche nach Filmen anhand von Genre oder Name hinzugefügt.
Fügen Sie Pages/Movies/Index.cshtml.cs
folgende hervorgehobene Anweisung und Eigenschaften hinzu:
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; }
Im vorherigen Code:
SearchString
: Enthält den Text, den Benutzer in das Suchtextfeld eingeben.SearchString
weist das Attribut[BindProperty]
auf.[BindProperty]
bindet Formularwerte und Abfragezeichenfolgen mit dem gleichen Namen wie die Eigenschaft.[BindProperty(SupportsGet = true)]
ist für die Bindung in HTTP GET-Anforderungen erforderlich.Genres
: Enthält die Liste der Genres.Genres
ermöglicht es dem Benutzer, ein Genre in der Liste auszuwählen.SelectList
erfordertusing Microsoft.AspNetCore.Mvc.Rendering;
.MovieGenre
: Enthält das spezifische vom Benutzer auswählte Genre. Beispiel: Western.Genres
undMovieGenre
werden später in diesem Tutorial verwendet.
Warnung
Aus Sicherheitsgründen müssen Sie Daten von GET
-Anforderungen in die Seitenmodelleigenschaften einbinden. Überprüfen Sie die Benutzereingaben, bevor Sie sie den Eigenschaften zuordnen. Die Verwendung der GET
-Bindung ist von Vorteil, wenn Sie Szenarios behandeln, die von Abfragezeichenfolgen oder Routenwerten abhängig sind.
Legen Sie die SupportsGet
-Eigenschaft des [BindProperty]
-Attributs auf true
fest, um eine Eigenschaft an GET
-Anforderungen zu binden:
[BindProperty(SupportsGet = true)]
Weitere Informationen finden Sie unter ASP.NET Core Community Standup: Binden auf GET-Diskussion (YouTube).
Aktualisieren Sie die OnGetAsync
-Methode der Indexseite mit folgendem Code:
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();
}
Die erste Zeile der OnGetAsync
-Methode erstellt eine LINQ-Abfrage zum Auswählen der Filme:
// using System.Linq;
var movies = from m in _context.Movie
select m;
Die Abfrage wird an diesem Punkt nur definiert. Sie wurde noch nicht auf die Datenbank angewendet.
Wenn die SearchString
-Eigenschaft nicht NULL oder leer ist, wird die Abfrage nach Filmen so geändert, dass die Suchzeichenfolge gefiltert wird:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Der Code s => s.Title.Contains()
ist ein Lambdaausdruck. Lambdaausdrücke werden in methodenbasierten LINQ-Abfragen als Argumente für standardmäßige Abfrageoperatormethoden wie die Where-Methode oder Contains
verwendet. LINQ-Abfragen werden nicht ausgeführt, wenn sie definiert oder durch Aufrufen einer Methode wie z. B. Where
, Contains
oder OrderBy
geändert werden. Stattdessen wird die Ausführung der Abfrage verzögert. Die Auswertung eines Ausdrucks wird so lange hinausgezögert, bis dessen realisierter Wert durchlaufen oder die ToListAsync
-Methode aufgerufen wird. Weitere Informationen finden Sie unter Abfrageausführung.
Hinweis
Die Contains-Methode wird in der Datenbank und nicht im C#-Code ausgeführt. Die Groß-/Kleinschreibung in der Abfrage hängt von der Datenbank und Sortierung ab. In SQL Server wird Contains
zu SQL LIKE zugeordnet, das Groß-/Kleinschreibung nicht beachtet. In SQLite mit der Standardsortierung wird die Groß-/Kleinschreibung abhängig von der Abfrage berücksichtigt oder NICHT berücksichtigt. Informationen dazu, wie Sie SQLite-Abfragen ohne Unterscheidung der Groß-/Kleinschreibung stellen, finden Sie in den folgenden Themen:
- Dieses GitHub-Issue.
- Dieses GitHub-Issue.
- Sortierungen und Unterscheidung nach Groß-/Kleinschreibung
Navigieren Sie zur Seite „Movies“, und fügen Sie eine Abfragezeichenfolge wie z. B. ?searchString=Ghost
an die URL an. Beispiel: https://localhost:5001/Movies?searchString=Ghost
. Die gefilterten Filme werden angezeigt.
Wenn die Routenvorlage der Indexseite hinzugefügt wird, kann die Suchzeichenfolge als URL-Segment übergeben werden. Beispiel: https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
Die vorangehende Routeneinschränkung ermöglicht das Suchen des Titels als Routendaten (URL-Segment) anstatt als Wert einer Abfragezeichenfolge. Das ?
in "{searchString?}"
bedeutet, dass dies ein optionaler Routenparameter ist.
Die ASP.NET Core-Runtime verwendet die Modellbindung, um den Wert der SearchString
-Eigenschaft aus der Abfragezeichenfolge (?searchString=Ghost
) oder aus Datenrouten (https://localhost:5001/Movies/Ghost
) festzulegen. Bei der Modellbindung wird Groß- und Kleinschreibung nicht berücksichtigt.
Sie können jedoch von Benutzern nicht erwarten, dass sie die URL ändern, um nach einem Film zu suchen. In diesem Schritt wird eine Benutzeroberflächenoption hinzugefügt, um Filme zu filtern. Wenn Sie die Routeneinschränkung "{searchString?}"
hinzugefügt haben, entfernen Sie sie.
Öffnen Sie die Datei Pages/Movies/Index.cshtml
, und fügen Sie im folgenden Code das hervorgehobene Markup hinzu:
@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.*@
Das HTML-Tag <form>
verwendet die folgenden Taghilfsprogramme:
- Hilfsprogramm für Formulartags. Bei der Übermittlung des Formulars wird die Filterzeichenfolge über die Abfragezeichenfolge an die Seite Pages/Movies/Index gesendet.
- Hilfsprogramm für Eingabetags
Speichern Sie die Änderungen, und testen Sie den Filter.
Suche nach Genre
Aktualisieren Sie die OnGetAsync
-Methode der Indexseite mit folgendem Code:
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();
}
Der folgende Code ist eine LINQ-Abfrage, die alle Genres aus der Datenbank abruft.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
Die SelectList
von Genres wird durch Projizieren der unterschiedlichen Genres erstellt.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Hinzufügen einer Suche anhand von Genre zur Razor Page
Aktualisieren Sie das
Index.cshtml
<form>
-Element wie im folgenden Markup hervorgehoben:@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.*@
Testen Sie die App mit einer Suche nach Genre, Filmtitel und beidem.