Sdílet prostřednictvím


Část 6: Přidání vyhledávání do ASP.NET základních Razor stránek

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Upozorňující

Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Důležité

Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Autor: Rick Anderson

V následujících částech se přidá hledání filmů podle žánru nebo názvu .

Přidejte následující zvýrazněný kód 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; }

V předchozím kódu:

  • SearchString: Obsahuje text, který uživatelé zadávají do vyhledávacího textového pole. SearchString[BindProperty] má atribut. [BindProperty] vytvoří vazbu hodnot formuláře a řetězců dotazu se stejným názvem jako vlastnost. [BindProperty(SupportsGet = true)] pro vazbu požadavků HTTP GET se vyžaduje.
  • Genres: Obsahuje seznam žánrů. Genres umožňuje uživateli vybrat ze seznamu žánr. SelectList požaduje using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre: Obsahuje konkrétní žánr, který uživatel vybere. Například "Západní".
  • Genres a MovieGenre používají se později v tomto kurzu.

Upozorňující

Z bezpečnostních důvodů musíte vyjádřit souhlas s vazbou dat požadavků GET na vlastnosti modelu stránky. Před mapováním uživatelského vstupu na vlastnosti tento vstup ověřte. Vyjádření souhlasu s vazbou požadavků GET je užitečné při řešení scénářů, které se spoléhají na řetězec dotazu nebo hodnoty trasy.

Pokud chcete vytvořit vazbu vlastnosti na požadavky GET, nastavte vlastnost SupportsGet atributu [BindProperty] na hodnotu true:

[BindProperty(SupportsGet = true)]

Další informace najdete ve videu Přehled novinek v komunitě ASP.NET Core: Diskuze k vazbě požadavků GET (YouTube).

Aktualizujte metodu Movies/Index OnGetAsync stránky následujícím kódem:

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();
}

První řádek OnGetAsync metody vytvoří dotaz LINQ pro výběr filmů:

var movies = from m in _context.Movie
             select m;

Dotaz je definován pouze v tomto okamžiku, nebyl spuštěn proti databázi.

SearchString Pokud vlastnost není nebo není null prázdná, dotaz filmy se upraví tak, aby filtrovaly hledaný řetězec:

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

Kód s => s.Title.Contains() je výraz lambda. Lambda se používají v dotazech LINQ založených na metodách jako argumenty pro standardní metody operátoru dotazu, jako je metoda Where nebo Contains. Dotazy LINQ se nespouštějí při jejich definování nebo úpravě voláním metody, například Where, Containsnebo OrderBy. Místo toho se odloží provádění dotazu. Vyhodnocení výrazu je zpožděné, dokud jeho dosažená hodnota není iterated over nebo ToListAsync metoda je volána. Další informace najdete v tématu Provádění dotazů.

Poznámka:

Metoda Contains se spouští v databázi, ne v kódu jazyka C#. Citlivost případu na dotazu závisí na databázi a kolaci. Na SQL Serveru Contains se mapuje na SQL LIKE, což je nerozlišující velká a malá písmena. SQLite s výchozí kolací je kombinace rozlišování velkých a malých a velkých písmen v závislosti na dotazu. Informace o rozlišování dotazů SQLite pro případ najdete v následujících tématech:

Přejděte na stránku Filmy a připojte řetězec dotazu, například ?searchString=Ghost k adrese URL. Například https://localhost:5001/Movies?searchString=Ghost. Zobrazí se filtrované filmy.

Zobrazení indexu

Pokud je na indexovou stránku přidána následující šablona trasy, může být hledaný řetězec předán jako segment adresy URL. Například https://localhost:5001/Movies/Ghost.

@page "{searchString?}"

Předchozí omezení trasy umožňuje prohledávat název jako směrovací data (segment adresy URL) místo jako hodnotu řetězce dotazu. "{searchString?}" Hodnota ? in znamená, že se jedná o volitelný parametr trasy.

Zobrazení rejstříku se slovem ghost přidaným na adresu URL a vráceným seznamem filmů se dvěma filmy, Ghostbusters a Ghostbusters 2

Modul runtime ASP.NET Core používá vazbu modelu k nastavení hodnoty SearchString vlastnosti z řetězce dotazu (?searchString=Ghost) nebo směrování dat (https://localhost:5001/Movies/Ghost). Vazba modelu nerozlišuje malá a velká písmena.

Uživatele ale nelze očekávat, že upraví adresu URL tak, aby hledala film. V tomto kroku se uživatelské rozhraní přidá k filtrování filmů. Pokud jste přidali omezení "{searchString?}"trasy, odeberte ho.

Pages/Movies/Index.cshtml Otevřete soubor a přidejte značku zvýrazněnou v následujícím kódu:

@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>

Značka HTML <form> používá následující pomocné rutiny značek:

Uložte změny a otestujte filtr.

Zobrazení rejstříku se slovem ghost napsaným do textového pole filtru nadpisu

Hledat podle žánru

Aktualizujte metodu Movies/Index.cshtml.cs stránky OnGetAsync následujícím kódem:

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();
}

Následující kód je dotaz LINQ, který načte všechny žánry z databáze.

IQueryable<string> genreQuery = from m in _context.Movie
                                orderby m.Genre
                                select m.Genre;

Žánry SelectList jsou vytvořeny promítnutím různých žánrů:

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

Přidání hledání podle žánru Razor na stránku

Index.cshtml<form> Aktualizujte prvek tak, jak je zvýrazněný v následujícím kódu:

@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>

Otestujte aplikaci vyhledáváním podle žánru, podle názvu filmu a obojího:

Zobrazení indexu dokončeno s filtry hledání v poli Žánr a Textové pole Nadpis

Další kroky

V následujících částech se přidá hledání filmů podle žánru nebo názvu .

Přidejte následující zvýrazněný kód 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; }

V předchozím kódu:

  • SearchString: Obsahuje text, který uživatelé zadávají do vyhledávacího textového pole. SearchString[BindProperty] má atribut. [BindProperty] vytvoří vazbu hodnot formuláře a řetězců dotazu se stejným názvem jako vlastnost. [BindProperty(SupportsGet = true)] pro vazbu požadavků HTTP GET se vyžaduje.
  • Genres: Obsahuje seznam žánrů. Genres umožňuje uživateli vybrat ze seznamu žánr. SelectList požaduje using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre: Obsahuje konkrétní žánr, který uživatel vybere. Například "Západní".
  • Genres a MovieGenre používají se později v tomto kurzu.

Upozorňující

Z bezpečnostních důvodů musíte vyjádřit souhlas s vazbou dat požadavků GET na vlastnosti modelu stránky. Před mapováním uživatelského vstupu na vlastnosti tento vstup ověřte. Vyjádření souhlasu s vazbou požadavků GET je užitečné při řešení scénářů, které se spoléhají na řetězec dotazu nebo hodnoty trasy.

Pokud chcete vytvořit vazbu vlastnosti na požadavky GET, nastavte vlastnost SupportsGet atributu [BindProperty] na hodnotu true:

[BindProperty(SupportsGet = true)]

Další informace najdete ve videu Přehled novinek v komunitě ASP.NET Core: Diskuze k vazbě požadavků GET (YouTube).

Aktualizujte metodu indexové stránky OnGetAsync následujícím kódem:

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();
}

První řádek OnGetAsync metody vytvoří dotaz LINQ pro výběr filmů:

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

Dotaz je definován pouze v tomto okamžiku, nebyl spuštěn proti databázi.

SearchString Pokud vlastnost není nebo není null prázdná, dotaz filmy se upraví tak, aby filtrovaly hledaný řetězec:

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

Kód s => s.Title.Contains() je výraz lambda. Lambda se používají v dotazech LINQ založených na metodách jako argumenty pro standardní metody operátoru dotazu, jako je metoda Where nebo Contains. Dotazy LINQ se nespouštějí při jejich definování nebo úpravě voláním metody, například Where, Containsnebo OrderBy. Místo toho se odloží provádění dotazu. Vyhodnocení výrazu je zpožděné, dokud jeho dosažená hodnota není iterated over nebo ToListAsync metoda je volána. Další informace najdete v tématu Provádění dotazů.

Poznámka:

Metoda Contains se spouští v databázi, ne v kódu jazyka C#. Citlivost případu na dotazu závisí na databázi a kolaci. Na SQL Serveru Contains se mapuje na SQL LIKE, což je nerozlišující velká a malá písmena. SQLite s výchozí kolací je kombinace rozlišování velkých a malých a velkých písmen v závislosti na dotazu. Informace o rozlišování dotazů SQLite pro případ najdete v následujících tématech:

Přejděte na stránku Filmy a připojte řetězec dotazu, například ?searchString=Ghost k adrese URL. Například https://localhost:5001/Movies?searchString=Ghost. Zobrazí se filtrované filmy.

Zobrazení indexu

Pokud je na indexovou stránku přidána následující šablona trasy, může být hledaný řetězec předán jako segment adresy URL. Například https://localhost:5001/Movies/Ghost.

@page "{searchString?}"

Předchozí omezení trasy umožňuje prohledávat název jako směrovací data (segment adresy URL) místo jako hodnotu řetězce dotazu. "{searchString?}" Hodnota ? in znamená, že se jedná o volitelný parametr trasy.

Zobrazení rejstříku se slovem ghost přidaným na adresu URL a vráceným seznamem filmů se dvěma filmy, Ghostbusters a Ghostbusters 2

Modul runtime ASP.NET Core používá vazbu modelu k nastavení hodnoty SearchString vlastnosti z řetězce dotazu (?searchString=Ghost) nebo směrování dat (https://localhost:5001/Movies/Ghost). Vazba modelu nerozlišuje malá a velká písmena.

Uživatele ale nelze očekávat, že upraví adresu URL tak, aby hledala film. V tomto kroku se uživatelské rozhraní přidá k filtrování filmů. Pokud jste přidali omezení "{searchString?}"trasy, odeberte ho.

Pages/Movies/Index.cshtml Otevřete soubor a přidejte značku zvýrazněnou v následujícím kódu:

@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.*@

Značka HTML <form> používá následující pomocné rutiny značek:

Uložte změny a otestujte filtr.

Zobrazení rejstříku se slovem ghost napsaným do textového pole filtru nadpisu

Hledat podle žánru

Aktualizujte metodu Movies/Index.cshtml.cs stránky OnGetAsync následujícím kódem:

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();
}

Následující kód je dotaz LINQ, který načte všechny žánry z databáze.

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

Žánry SelectList se vytvářejí tak, že promítnou různé žánry.

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

Přidání hledání podle žánru Razor na stránku

Index.cshtml<form> Aktualizujte prvek tak, jak je zvýrazněný v následujícím kódu:

@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>

Otestujte aplikaci hledáním podle žánru, podle názvu filmu a obojího.

Další kroky

V následujících částech se přidá hledání filmů podle žánru nebo názvu .

Přidejte následující zvýrazněný kód 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; }

V předchozím kódu:

  • SearchString: Obsahuje text, který uživatelé zadávají do vyhledávacího textového pole. SearchString[BindProperty] má atribut. [BindProperty] vytvoří vazbu hodnot formuláře a řetězců dotazu se stejným názvem jako vlastnost. [BindProperty(SupportsGet = true)] pro vazbu požadavků HTTP GET se vyžaduje.
  • Genres: Obsahuje seznam žánrů. Genres umožňuje uživateli vybrat ze seznamu žánr. SelectList požaduje using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre: Obsahuje konkrétní žánr, který uživatel vybere. Například "Západní".
  • Genres a MovieGenre používají se později v tomto kurzu.

Upozorňující

Z bezpečnostních důvodů musíte vyjádřit souhlas s vazbou dat požadavků GET na vlastnosti modelu stránky. Před mapováním uživatelského vstupu na vlastnosti tento vstup ověřte. Vyjádření souhlasu s vazbou požadavků GET je užitečné při řešení scénářů, které se spoléhají na řetězec dotazu nebo hodnoty trasy.

Pokud chcete vytvořit vazbu vlastnosti na požadavky GET, nastavte vlastnost SupportsGet atributu [BindProperty] na hodnotu true:

[BindProperty(SupportsGet = true)]

Další informace najdete ve videu Přehled novinek v komunitě ASP.NET Core: Diskuze k vazbě požadavků GET (YouTube).

Aktualizujte metodu indexové stránky OnGetAsync následujícím kódem:

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();
}

První řádek OnGetAsync metody vytvoří dotaz LINQ pro výběr filmů:

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

Dotaz je definován pouze v tomto okamžiku, nebyl spuštěn proti databázi.

SearchString Pokud vlastnost není nebo není null prázdná, dotaz filmy se upraví tak, aby filtrovaly hledaný řetězec:

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

Kód s => s.Title.Contains() je výraz lambda. Lambda se používají v dotazech LINQ založených na metodách jako argumenty pro standardní metody operátoru dotazu, jako je metoda Where nebo Contains. Dotazy LINQ se nespouštějí při jejich definování nebo úpravě voláním metody, například Where, Containsnebo OrderBy. Místo toho se odloží provádění dotazu. Vyhodnocení výrazu je zpožděné, dokud jeho dosažená hodnota není iterated over nebo ToListAsync metoda je volána. Další informace najdete v tématu Provádění dotazů.

Poznámka:

Metoda Contains se spouští v databázi, ne v kódu jazyka C#. Citlivost případu na dotazu závisí na databázi a kolaci. Na SQL Serveru Contains se mapuje na SQL LIKE, což je nerozlišující velká a malá písmena. SQLite s výchozí kolací je kombinace rozlišování velkých a malých a velkých písmen v závislosti na dotazu. Informace o rozlišování dotazů SQLite pro případ najdete v následujících tématech:

Přejděte na stránku Filmy a připojte řetězec dotazu, například ?searchString=Ghost k adrese URL. Například https://localhost:5001/Movies?searchString=Ghost. Zobrazí se filtrované filmy.

Zobrazení indexu

Pokud je na indexovou stránku přidána následující šablona trasy, může být hledaný řetězec předán jako segment adresy URL. Například https://localhost:5001/Movies/Ghost.

@page "{searchString?}"

Předchozí omezení trasy umožňuje prohledávat název jako směrovací data (segment adresy URL) místo jako hodnotu řetězce dotazu. "{searchString?}" Hodnota ? in znamená, že se jedná o volitelný parametr trasy.

Zobrazení rejstříku se slovem ghost přidaným na adresu URL a vráceným seznamem filmů se dvěma filmy, Ghostbusters a Ghostbusters 2

Modul runtime ASP.NET Core používá vazbu modelu k nastavení hodnoty SearchString vlastnosti z řetězce dotazu (?searchString=Ghost) nebo směrování dat (https://localhost:5001/Movies/Ghost). Vazba modelu nerozlišuje malá a velká písmena.

Uživatele ale nelze očekávat, že upraví adresu URL tak, aby hledala film. V tomto kroku se uživatelské rozhraní přidá k filtrování filmů. Pokud jste přidali omezení "{searchString?}"trasy, odeberte ho.

Pages/Movies/Index.cshtml Otevřete soubor a přidejte značku zvýrazněnou v následujícím kódu:

@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.*@

Značka HTML <form> používá následující pomocné rutiny značek:

Uložte změny a otestujte filtr.

Zobrazení rejstříku se slovem ghost napsaným do textového pole filtru nadpisu

Hledat podle žánru

Aktualizujte metodu indexové stránky OnGetAsync následujícím kódem:

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();
}

Následující kód je dotaz LINQ, který načte všechny žánry z databáze.

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

Žánry SelectList se vytvářejí tak, že promítnou různé žánry.

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

Přidání hledání podle žánru Razor na stránku

Index.cshtml<form> Aktualizujte prvek tak, jak je zvýrazněný v následujícím kódu:

@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>

Otestujte aplikaci hledáním podle žánru, podle názvu filmu a obojího.

Další kroky

V následujících částech se přidá hledání filmů podle žánru nebo názvu .

Přidejte následující zvýrazněný kód 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; }

V předchozím kódu:

  • SearchString: Obsahuje text, který uživatelé zadávají do vyhledávacího textového pole. SearchString[BindProperty] má atribut. [BindProperty] vytvoří vazbu hodnot formuláře a řetězců dotazu se stejným názvem jako vlastnost. [BindProperty(SupportsGet = true)] pro vazbu požadavků HTTP GET se vyžaduje.
  • Genres: Obsahuje seznam žánrů. Genres umožňuje uživateli vybrat ze seznamu žánr. SelectList požaduje using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre: Obsahuje konkrétní žánr, který uživatel vybere. Například "Západní".
  • Genres a MovieGenre používají se později v tomto kurzu.

Upozorňující

Z bezpečnostních důvodů musíte vyjádřit souhlas s vazbou dat požadavků GET na vlastnosti modelu stránky. Před mapováním uživatelského vstupu na vlastnosti tento vstup ověřte. Vyjádření souhlasu s vazbou požadavků GET je užitečné při řešení scénářů, které se spoléhají na řetězec dotazu nebo hodnoty trasy.

Pokud chcete vytvořit vazbu vlastnosti na požadavky GET, nastavte vlastnost SupportsGet atributu [BindProperty] na hodnotu true:

[BindProperty(SupportsGet = true)]

Další informace najdete ve videu Přehled novinek v komunitě ASP.NET Core: Diskuze k vazbě požadavků GET (YouTube).

Aktualizujte metodu indexové stránky OnGetAsync následujícím kódem:

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();
}

První řádek OnGetAsync metody vytvoří dotaz LINQ pro výběr filmů:

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

Dotaz je definován pouze v tomto okamžiku, nebyl spuštěn proti databázi.

SearchString Pokud vlastnost není null nebo prázdná, dotaz filmy se upraví tak, aby filtrovaly hledaný řetězec:

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

Kód s => s.Title.Contains() je výraz lambda. Lambda se používají v dotazech LINQ založených na metodách jako argumenty pro standardní metody operátoru dotazu, jako je metoda Where nebo Contains. Dotazy LINQ se nespouštějí při jejich definování nebo úpravě voláním metody, například Where, Containsnebo OrderBy. Místo toho se odloží provádění dotazu. Vyhodnocení výrazu je zpožděné, dokud jeho dosažená hodnota není iterated over nebo ToListAsync metoda je volána. Další informace najdete v tématu Provádění dotazů.

Poznámka:

Metoda Contains se spouští v databázi, ne v kódu jazyka C#. Citlivost případu na dotazu závisí na databázi a kolaci. Na SQL Serveru Contains se mapuje na SQL LIKE, což je nerozlišující velká a malá písmena. SQLite s výchozí kolací je kombinace rozlišování velkých a malých a velkých písmen v závislosti na dotazu. Informace o rozlišování dotazů SQLite pro případ najdete v následujících tématech:

Přejděte na stránku Filmy a připojte řetězec dotazu, například ?searchString=Ghost k adrese URL. Například https://localhost:5001/Movies?searchString=Ghost. Zobrazí se filtrované filmy.

Zobrazení indexu

Pokud je na indexovou stránku přidána následující šablona trasy, může být hledaný řetězec předán jako segment adresy URL. Například https://localhost:5001/Movies/Ghost.

@page "{searchString?}"

Předchozí omezení trasy umožňuje prohledávat název jako směrovací data (segment adresy URL) místo jako hodnotu řetězce dotazu. "{searchString?}" Hodnota ? in znamená, že se jedná o volitelný parametr trasy.

Zobrazení rejstříku se slovem ghost přidaným na adresu URL a vráceným seznamem filmů se dvěma filmy, Ghostbusters a Ghostbusters 2

Modul runtime ASP.NET Core používá vazbu modelu k nastavení hodnoty SearchString vlastnosti z řetězce dotazu (?searchString=Ghost) nebo směrování dat (https://localhost:5001/Movies/Ghost). Vazba modelu nerozlišuje malá a velká písmena.

Uživatele ale nelze očekávat, že upraví adresu URL tak, aby hledala film. V tomto kroku se uživatelské rozhraní přidá k filtrování filmů. Pokud jste přidali omezení "{searchString?}"trasy, odeberte ho.

Pages/Movies/Index.cshtml Otevřete soubor a přidejte značku zvýrazněnou v následujícím kódu:

@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.*@

Značka HTML <form> používá následující pomocné rutiny značek:

Uložte změny a otestujte filtr.

Zobrazení rejstříku se slovem ghost napsaným do textového pole filtru nadpisu

Hledat podle žánru

Aktualizujte metodu indexové stránky OnGetAsync následujícím kódem:

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();
}

Následující kód je dotaz LINQ, který načte všechny žánry z databáze.

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

Žánry SelectList se vytvářejí tak, že promítnou různé žánry.

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

Přidání hledání podle žánru Razor na stránku

Index.cshtml<form> Aktualizujte prvek tak, jak je zvýrazněný v následujícím kódu:

@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>

Otestujte aplikaci hledáním podle žánru, podle názvu filmu a obojího.

Další kroky

V následujících částech se přidá hledání filmů podle žánru nebo názvu .

Přidejte následující zvýrazněný příkaz using a vlastnosti 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; }
        [BindProperty(SupportsGet = true)]
        public string SearchString { get; set; }
        public SelectList Genres { get; set; }
        [BindProperty(SupportsGet = true)]
        public string MovieGenre { get; set; }

V předchozím kódu:

  • SearchString: Obsahuje text, který uživatelé zadávají do vyhledávacího textového pole. SearchString[BindProperty] má atribut. [BindProperty] vytvoří vazbu hodnot formuláře a řetězců dotazu se stejným názvem jako vlastnost. [BindProperty(SupportsGet = true)] pro vazbu požadavků HTTP GET se vyžaduje.
  • Genres: Obsahuje seznam žánrů. Genres umožňuje uživateli vybrat ze seznamu žánr. SelectList požaduje using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre: Obsahuje konkrétní žánr, který uživatel vybere. Například "Západní".
  • Genres a MovieGenre používají se později v tomto kurzu.

Upozorňující

Z bezpečnostních důvodů musíte vyjádřit souhlas s vazbou dat požadavků GET na vlastnosti modelu stránky. Před mapováním uživatelského vstupu na vlastnosti tento vstup ověřte. Vyjádření souhlasu s vazbou požadavků GET je užitečné při řešení scénářů, které se spoléhají na řetězec dotazu nebo hodnoty trasy.

Pokud chcete vytvořit vazbu vlastnosti na požadavky GET, nastavte vlastnost SupportsGet atributu [BindProperty] na hodnotu true:

[BindProperty(SupportsGet = true)]

Další informace najdete ve videu Přehled novinek v komunitě ASP.NET Core: Diskuze k vazbě požadavků GET (YouTube).

Aktualizujte metodu indexové stránky OnGetAsync následujícím kódem:

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();
}

První řádek OnGetAsync metody vytvoří dotaz LINQ pro výběr filmů:

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

Dotaz je definován pouze v tomto okamžiku, nebyl spuštěn proti databázi.

SearchString Pokud vlastnost není null nebo prázdná, dotaz filmy se upraví tak, aby filtrovaly hledaný řetězec:

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

Kód s => s.Title.Contains() je výraz lambda. Lambda se používají v dotazech LINQ založených na metodách jako argumenty pro standardní metody operátoru dotazu, jako je metoda Where nebo Contains. Dotazy LINQ se nespouštějí při jejich definování nebo úpravě voláním metody, například Where, Containsnebo OrderBy. Místo toho se odloží provádění dotazu. Vyhodnocení výrazu je zpožděné, dokud jeho dosažená hodnota není iterated over nebo ToListAsync metoda je volána. Další informace najdete v tématu Provádění dotazů.

Poznámka:

Metoda Contains se spouští v databázi, ne v kódu jazyka C#. Citlivost případu na dotazu závisí na databázi a kolaci. Na SQL Serveru Contains se mapuje na SQL LIKE, což je nerozlišující velká a malá písmena. SQLite s výchozí kolací je kombinace rozlišování velkých a malých a velkých písmen v závislosti na dotazu. Informace o rozlišování dotazů SQLite pro případ najdete v následujících tématech:

Přejděte na stránku Filmy a připojte řetězec dotazu, například ?searchString=Ghost k adrese URL. Například https://localhost:5001/Movies?searchString=Ghost. Zobrazí se filtrované filmy.

Zobrazení indexu

Pokud je na indexovou stránku přidána následující šablona trasy, může být hledaný řetězec předán jako segment adresy URL. Například https://localhost:5001/Movies/Ghost.

@page "{searchString?}"

Předchozí omezení trasy umožňuje prohledávat název jako směrovací data (segment adresy URL) místo jako hodnotu řetězce dotazu. "{searchString?}" Hodnota ? in znamená, že se jedná o volitelný parametr trasy.

Zobrazení rejstříku se slovem ghost přidaným na adresu URL a vráceným seznamem filmů se dvěma filmy, Ghostbusters a Ghostbusters 2

Modul runtime ASP.NET Core používá vazbu modelu k nastavení hodnoty SearchString vlastnosti z řetězce dotazu (?searchString=Ghost) nebo směrování dat (https://localhost:5001/Movies/Ghost). Vazba modelu nerozlišuje malá a velká písmena.

Uživatele ale nelze očekávat, že upraví adresu URL tak, aby hledala film. V tomto kroku se uživatelské rozhraní přidá k filtrování filmů. Pokud jste přidali omezení "{searchString?}"trasy, odeberte ho.

Pages/Movies/Index.cshtml Otevřete soubor a přidejte značku zvýrazněnou v následujícím kódu:

@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.*@

Značka HTML <form> používá následující pomocné rutiny značek:

Uložte změny a otestujte filtr.

Zobrazení rejstříku se slovem ghost napsaným do textového pole filtru nadpisu

Hledat podle žánru

Aktualizujte metodu indexové stránky OnGetAsync následujícím kódem:

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();
}

Následující kód je dotaz LINQ, který načte všechny žánry z databáze.

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

Žánry SelectList se vytvářejí tak, že promítnou různé žánry.

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

Přidání hledání podle žánru Razor na stránku

  1. Index.cshtml<form> Aktualizujte prvek tak, jak je zvýrazněný v následujícím kódu:

    @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. Otestujte aplikaci hledáním podle žánru, podle názvu filmu a obojího.

Další kroky