Freigeben über


Teil 6: Hinzufügen der Suche zu Razor Pages in ASP.NET Core

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Warnung

Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der Supportrichtlinie für .NET und .NET Core. Informationen zum aktuellen Release finden Sie in der .NET 8-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.

Informationen zum aktuellen Release finden Sie in der .NET 8-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 erfordert using Microsoft.AspNetCore.Mvc.Rendering;.
  • MovieGenre: Enthält das spezifische vom Benutzer auswählte Genre. Beispiel: Western.
  • Genres und MovieGenre 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.

Indexansicht

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.

Indexansicht mit dem der URL hinzugefügten Wort „ghost“ und einer zurückgegebenen Filmliste mit zwei Filmen: Ghostbusters und Ghostbusters 2

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:

Speichern Sie die Änderungen, und testen Sie den Filter.

Indexansicht mit dem in das Filtertextfeld eingegebenen Wort „ghost“

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:

Vollständige Indexansicht mit Suchfiltern „Genreauswahl“ und „Titeltextbox“

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 erfordert using Microsoft.AspNetCore.Mvc.Rendering;.
  • MovieGenre: Enthält das spezifische vom Benutzer auswählte Genre. Beispiel: Western.
  • Genres und MovieGenre 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.

Indexansicht

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.

Indexansicht mit dem der URL hinzugefügten Wort „ghost“ und einer zurückgegebenen Filmliste mit zwei Filmen: Ghostbusters und Ghostbusters 2

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:

Speichern Sie die Änderungen, und testen Sie den Filter.

Indexansicht mit dem in das Filtertextfeld eingegebenen Wort „ghost“

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 erfordert using Microsoft.AspNetCore.Mvc.Rendering;.
  • MovieGenre: Enthält das spezifische vom Benutzer auswählte Genre. Beispiel: Western.
  • Genres und MovieGenre 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.

Indexansicht

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.

Indexansicht mit dem der URL hinzugefügten Wort „ghost“ und einer zurückgegebenen Filmliste mit zwei Filmen: Ghostbusters und Ghostbusters 2

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:

Speichern Sie die Änderungen, und testen Sie den Filter.

Indexansicht mit dem in das Filtertextfeld eingegebenen Wort „ghost“

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 erfordert using Microsoft.AspNetCore.Mvc.Rendering;.
  • MovieGenre: Enthält das spezifische vom Benutzer auswählte Genre. Beispiel: Western.
  • Genres und MovieGenre 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.

Indexansicht

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.

Indexansicht mit dem der URL hinzugefügten Wort „ghost“ und einer zurückgegebenen Filmliste mit zwei Filmen: Ghostbusters und Ghostbusters 2

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:

Speichern Sie die Änderungen, und testen Sie den Filter.

Indexansicht mit dem in das Filtertextfeld eingegebenen Wort „ghost“

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 erfordert using Microsoft.AspNetCore.Mvc.Rendering;.
  • MovieGenre: Enthält das spezifische vom Benutzer auswählte Genre. Beispiel: Western.
  • Genres und MovieGenre 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.

Indexansicht

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.

Indexansicht mit dem der URL hinzugefügten Wort „ghost“ und einer zurückgegebenen Filmliste mit zwei Filmen: Ghostbusters und Ghostbusters 2

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:

Speichern Sie die Änderungen, und testen Sie den Filter.

Indexansicht mit dem in das Filtertextfeld eingegebenen Wort „ghost“

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

  1. 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.*@
    
    
  2. Testen Sie die App mit einer Suche nach Genre, Filmtitel und beidem.

Nächste Schritte