Część 6. Dodawanie wyszukiwania do ASP.NET Core Razor Pages

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zapoznaj się z wersją tego artykułu platformy .NET 8.

Autor: Rick Anderson

W poniższych sekcjach dodano wyszukiwanie filmów według gatunku lub nazwy .

Dodaj następujący wyróżniony kod do :Pages/Movies/Index.cshtml.cs

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

    public IList<Movie> Movie { get;set; }  = default!;

    [BindProperty(SupportsGet = true)]
    public string? SearchString { get; set; }

    public SelectList? Genres { get; set; }

    [BindProperty(SupportsGet = true)]
    public string? MovieGenre { get; set; }

W poprzednim kodzie:

  • SearchString: zawiera tekst, który użytkownicy wprowadzają w polu tekstowym wyszukiwania. SearchString[BindProperty] ma atrybut . [BindProperty] Wiąże wartości formularza i ciągi zapytania o taką samą nazwę jak właściwość. [BindProperty(SupportsGet = true)] jest wymagany do wiązania żądań HTTP GET.
  • Genres: zawiera listę gatunków. Genres umożliwia użytkownikowi wybranie gatunku z listy. SelectList Wymaga using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre: zawiera określony gatunek wybierany przez użytkownika. Na przykład "Western".
  • Genres i MovieGenre są używane w dalszej części tego samouczka.

Ostrzeżenie

Ze względów bezpieczeństwa należy wyrazić zgodę na powiązanie danych żądania GET z właściwościami modelu strony. Przed mapowaniem danych wejściowych użytkownika na właściwości zweryfikuj je. Wyrażenie zgody na powiązanie danych GET jest przydatne w scenariuszach, które wykorzystują ciągi zapytania lub wartości trasy.

Aby powiązać właściwość w przypadku żądań GET, ustaw właściwość SupportsGet atrybutu [BindProperty] na true:

[BindProperty(SupportsGet = true)]

Aby uzyskać więcej informacji, zobacz Podsumowanie ASP.NET Core Community Standup: dyskusja na temat powiązania z użyciem metody GET (YouTube).

Zaktualizuj metodę strony indeksu OnGetAsync przy użyciu następującego kodu:

public async Task OnGetAsync()
{
    var movies = from m in _context.Movie
                 select m;
    if (!string.IsNullOrEmpty(SearchString))
    {
        movies = movies.Where(s => s.Title.Contains(SearchString));
    }

    Movie = await movies.ToListAsync();
}

Pierwszy wiersz OnGetAsync metody tworzy zapytanie LINQ w celu wybrania filmów:

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

Zapytanie jest zdefiniowane tylko w tym momencie, nie zostało ono uruchomione względem bazy danych.

SearchString Jeśli właściwość nie null jest pusta lub nie jest pusta, zapytanie o filmy jest modyfikowane w celu filtrowania w ciągu wyszukiwania:

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

Kod s => s.Title.Contains() jest wyrażeniem lambda. Wyrażenia lambda są używane w zapytaniach LINQ opartych na metodzie jako argumentach do standardowych metod operatorów zapytań, takich jak metoda Where lub Contains. Zapytania LINQ nie są wykonywane podczas ich definiowania lub modyfikacji przez wywołanie metody, takiej jak Where, Containslub OrderBy. Zamiast tego wykonywanie zapytań jest odroczone. Obliczanie wyrażenia jest opóźnione do momentu, aż jego zrealizowana wartość zostanie iterowana lub ToListAsync wywołana metoda. Aby uzyskać więcej informacji, zobacz Wykonywanie zapytań.

Uwaga

Metoda Contains jest uruchamiana w bazie danych, a nie w kodzie języka C#. Ważność wielkości liter w zapytaniu zależy od bazy danych i sortowania. W programie SQL Server Contains mapuje na sql LIKE, co jest bez uwzględniania wielkości liter. SqLite z sortowaniem domyślnym jest kombinacją wielkości liter i wielkości liter w rozróżnianiu w zależności od zapytania. Aby uzyskać informacje na temat tworzenia zapytań SQLite bez uwzględniania wielkości liter, zobacz następujące kwestie:

Przejdź do strony Filmy i dołącz ciąg zapytania, taki jak ?searchString=Ghost adres URL. Na przykład https://localhost:5001/Movies?searchString=Ghost. Zostaną wyświetlone przefiltrowane filmy.

Widok indeksu

Jeśli następujący szablon trasy zostanie dodany do strony Indeks, ciąg wyszukiwania można przekazać jako segment adresu URL. Na przykład https://localhost:5001/Movies/Ghost.

@page "{searchString?}"

Powyższe ograniczenie trasy umożliwia przeszukiwanie tytułu jako danych trasy (segment adresu URL) zamiast jako wartości ciągu zapytania. Wartość ? in "{searchString?}" oznacza, że jest to opcjonalny parametr trasy.

Widok indeksu ze słowem ghost dodanym do adresu URL i zwróconą listą filmów: Ghostbusters i Ghostbusters 2

Środowisko uruchomieniowe ASP.NET Core używa powiązania modelu, aby ustawić wartość SearchString właściwości z ciągu zapytania (?searchString=Ghost) lub danych trasy (https://localhost:5001/Movies/Ghost). Powiązanie modelu nie uwzględnia wielkości liter.

Nie można jednak oczekiwać zmodyfikowania adresu URL w celu wyszukania filmu. W tym kroku interfejs użytkownika jest dodawany do filtrowania filmów. Jeśli dodano ograniczenie "{searchString?}"trasy, usuń go.

Pages/Movies/Index.cshtml Otwórz plik i dodaj znacznik wyróżniony w następującym kodzie:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>

<form>
    <p>
        Title: <input type="text" asp-for="SearchString" />
        <input type="submit" value="Filter" />
    </p>
</form>

<table class="table">
    @*Markup removed for brevity.*@

Tag HTML <form> używa następujących pomocników tagów:

Zapisz zmiany i przetestuj filtr.

Widok indeksu ze słowem ghost wpisanym w polu tekstowym Filtr tytułu

Wyszukiwanie według gatunku

Zaktualizuj metodę Movies/Index.cshtml.cs page OnGetAsync przy użyciu następującego kodu:

public async Task OnGetAsync()
{
    // Use LINQ to get list of genres.
    IQueryable<string> genreQuery = from m in _context.Movie
                                    orderby m.Genre
                                    select m.Genre;

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

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

    if (!string.IsNullOrEmpty(MovieGenre))
    {
        movies = movies.Where(x => x.Genre == MovieGenre);
    }
    Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
    Movie = await movies.ToListAsync();
}

Poniższy kod to zapytanie LINQ, które pobiera wszystkie gatunki z bazy danych.

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

Gatunek SelectList jest tworzony przez projekcję odrębnych gatunków.

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

Dodawanie wyszukiwania według gatunku Razor do strony

Index.cshtml<form>Zaktualizuj element jako wyróżniony w następującym znaczniku:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>

<form>
    <p>
        <select asp-for="MovieGenre" asp-items="Model.Genres">
            <option value="">All</option>
        </select>
        Title: <input type="text" asp-for="SearchString" />
        <input type="submit" value="Filter" />
    </p>
</form>

Przetestuj aplikację, wyszukując według gatunku, według tytułu filmu i obu.

Następne kroki

W poniższych sekcjach dodano wyszukiwanie filmów według gatunku lub nazwy .

Dodaj następujący wyróżniony kod do :Pages/Movies/Index.cshtml.cs

public class IndexModel : PageModel
{
    private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

    public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
    {
        _context = context;
    }

    public IList<Movie> Movie { get;set; }  = default!;

    [BindProperty(SupportsGet = true)]
    public string? SearchString { get; set; }

    public SelectList? Genres { get; set; }

    [BindProperty(SupportsGet = true)]
    public string? MovieGenre { get; set; }

W poprzednim kodzie:

  • SearchString: zawiera tekst, który użytkownicy wprowadzają w polu tekstowym wyszukiwania. SearchString[BindProperty] ma atrybut . [BindProperty] Wiąże wartości formularza i ciągi zapytania o taką samą nazwę jak właściwość. [BindProperty(SupportsGet = true)] jest wymagany do wiązania żądań HTTP GET.
  • Genres: zawiera listę gatunków. Genres umożliwia użytkownikowi wybranie gatunku z listy. SelectList Wymaga using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre: zawiera określony gatunek wybierany przez użytkownika. Na przykład "Western".
  • Genres i MovieGenre są używane w dalszej części tego samouczka.

Ostrzeżenie

Ze względów bezpieczeństwa należy wyrazić zgodę na powiązanie danych żądania GET z właściwościami modelu strony. Przed mapowaniem danych wejściowych użytkownika na właściwości zweryfikuj je. Wyrażenie zgody na powiązanie danych GET jest przydatne w scenariuszach, które wykorzystują ciągi zapytania lub wartości trasy.

Aby powiązać właściwość w przypadku żądań GET, ustaw właściwość SupportsGet atrybutu [BindProperty] na true:

[BindProperty(SupportsGet = true)]

Aby uzyskać więcej informacji, zobacz Podsumowanie ASP.NET Core Community Standup: dyskusja na temat powiązania z użyciem metody GET (YouTube).

Zaktualizuj metodę strony indeksu OnGetAsync przy użyciu następującego kodu:

public async Task OnGetAsync()
{
    var movies = from m in _context.Movie
                 select m;
    if (!string.IsNullOrEmpty(SearchString))
    {
        movies = movies.Where(s => s.Title.Contains(SearchString));
    }

    Movie = await movies.ToListAsync();
}

Pierwszy wiersz OnGetAsync metody tworzy zapytanie LINQ w celu wybrania filmów:

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

Zapytanie jest zdefiniowane tylko w tym momencie, nie zostało ono uruchomione względem bazy danych.

SearchString Jeśli właściwość nie null jest pusta lub nie jest pusta, zapytanie o filmy jest modyfikowane w celu filtrowania w ciągu wyszukiwania:

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

Kod s => s.Title.Contains() jest wyrażeniem lambda. Wyrażenia lambda są używane w zapytaniach LINQ opartych na metodzie jako argumentach do standardowych metod operatorów zapytań, takich jak metoda Where lub Contains. Zapytania LINQ nie są wykonywane podczas ich definiowania lub modyfikacji przez wywołanie metody, takiej jak Where, Containslub OrderBy. Zamiast tego wykonywanie zapytań jest odroczone. Obliczanie wyrażenia jest opóźnione do momentu, aż jego zrealizowana wartość zostanie iterowana lub ToListAsync wywołana metoda. Aby uzyskać więcej informacji, zobacz Wykonywanie zapytań.

Uwaga

Metoda Contains jest uruchamiana w bazie danych, a nie w kodzie języka C#. Ważność wielkości liter w zapytaniu zależy od bazy danych i sortowania. W programie SQL Server Contains mapuje na sql LIKE, co jest bez uwzględniania wielkości liter. SqLite z sortowaniem domyślnym jest kombinacją wielkości liter i wielkości liter w rozróżnianiu w zależności od zapytania. Aby uzyskać informacje na temat tworzenia zapytań SQLite bez uwzględniania wielkości liter, zobacz następujące kwestie:

Przejdź do strony Filmy i dołącz ciąg zapytania, taki jak ?searchString=Ghost adres URL. Na przykład https://localhost:5001/Movies?searchString=Ghost. Zostaną wyświetlone przefiltrowane filmy.

Widok indeksu

Jeśli następujący szablon trasy zostanie dodany do strony Indeks, ciąg wyszukiwania można przekazać jako segment adresu URL. Na przykład https://localhost:5001/Movies/Ghost.

@page "{searchString?}"

Powyższe ograniczenie trasy umożliwia przeszukiwanie tytułu jako danych trasy (segment adresu URL) zamiast jako wartości ciągu zapytania. Wartość ? in "{searchString?}" oznacza, że jest to opcjonalny parametr trasy.

Widok indeksu ze słowem ghost dodanym do adresu URL i zwróconą listą filmów: Ghostbusters i Ghostbusters 2

Środowisko uruchomieniowe ASP.NET Core używa powiązania modelu, aby ustawić wartość SearchString właściwości z ciągu zapytania (?searchString=Ghost) lub danych trasy (https://localhost:5001/Movies/Ghost). Powiązanie modelu nie uwzględnia wielkości liter.

Nie można jednak oczekiwać zmodyfikowania adresu URL w celu wyszukania filmu. W tym kroku interfejs użytkownika jest dodawany do filtrowania filmów. Jeśli dodano ograniczenie "{searchString?}"trasy, usuń go.

Pages/Movies/Index.cshtml Otwórz plik i dodaj znacznik wyróżniony w następującym kodzie:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>

<form>
    <p>
        Title: <input type="text" asp-for="SearchString" />
        <input type="submit" value="Filter" />
    </p>
</form>

<table class="table">
    @*Markup removed for brevity.*@

Tag HTML <form> używa następujących pomocników tagów:

Zapisz zmiany i przetestuj filtr.

Widok indeksu ze słowem ghost wpisanym w polu tekstowym Filtr tytułu

Wyszukiwanie według gatunku

Zaktualizuj metodę strony indeksu OnGetAsync przy użyciu następującego kodu:

public async Task OnGetAsync()
{
    // Use LINQ to get list of genres.
    IQueryable<string> genreQuery = from m in _context.Movie
                                    orderby m.Genre
                                    select m.Genre;

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

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

    if (!string.IsNullOrEmpty(MovieGenre))
    {
        movies = movies.Where(x => x.Genre == MovieGenre);
    }
    Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
    Movie = await movies.ToListAsync();
}

Poniższy kod to zapytanie LINQ, które pobiera wszystkie gatunki z bazy danych.

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

Gatunek SelectList jest tworzony przez projekcję odrębnych gatunków.

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

Dodawanie wyszukiwania według gatunku Razor do strony

Index.cshtml<form>Zaktualizuj element jako wyróżniony w następującym znaczniku:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>

<form>
    <p>
        <select asp-for="MovieGenre" asp-items="Model.Genres">
            <option value="">All</option>
        </select>
        Title: <input type="text" asp-for="SearchString" />
        <input type="submit" value="Filter" />
    </p>
</form>

Przetestuj aplikację, wyszukując według gatunku, według tytułu filmu i obu.

Następne kroki

W poniższych sekcjach dodano wyszukiwanie filmów według gatunku lub nazwy .

Dodaj następujący wyróżniony kod do :Pages/Movies/Index.cshtml.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{
    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IList<Movie> Movie { get;set; } = default!;
        [BindProperty(SupportsGet = true)]
        public string ? SearchString { get; set; }
        public SelectList ? Genres { get; set; }
        [BindProperty(SupportsGet = true)]
        public string ? MovieGenre { get; set; }

W poprzednim kodzie:

  • SearchString: zawiera tekst, który użytkownicy wprowadzają w polu tekstowym wyszukiwania. SearchString[BindProperty] ma atrybut . [BindProperty] Wiąże wartości formularza i ciągi zapytania o taką samą nazwę jak właściwość. [BindProperty(SupportsGet = true)] jest wymagany do wiązania żądań HTTP GET.
  • Genres: zawiera listę gatunków. Genres umożliwia użytkownikowi wybranie gatunku z listy. SelectList Wymaga using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre: zawiera określony gatunek wybierany przez użytkownika. Na przykład "Western".
  • Genres i MovieGenre są używane w dalszej części tego samouczka.

Ostrzeżenie

Ze względów bezpieczeństwa należy wyrazić zgodę na powiązanie danych żądania GET z właściwościami modelu strony. Przed mapowaniem danych wejściowych użytkownika na właściwości zweryfikuj je. Wyrażenie zgody na powiązanie danych GET jest przydatne w scenariuszach, które wykorzystują ciągi zapytania lub wartości trasy.

Aby powiązać właściwość w przypadku żądań GET, ustaw właściwość SupportsGet atrybutu [BindProperty] na true:

[BindProperty(SupportsGet = true)]

Aby uzyskać więcej informacji, zobacz Podsumowanie ASP.NET Core Community Standup: dyskusja na temat powiązania z użyciem metody GET (YouTube).

Zaktualizuj metodę strony indeksu OnGetAsync przy użyciu następującego kodu:

public async Task OnGetAsync()
{
    var movies = from m in _context.Movie
                 select m;
    if (!string.IsNullOrEmpty(SearchString))
    {
        movies = movies.Where(s => s.Title.Contains(SearchString));
    }

    Movie = await movies.ToListAsync();
}

Pierwszy wiersz OnGetAsync metody tworzy zapytanie LINQ w celu wybrania filmów:

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

Zapytanie jest zdefiniowane tylko w tym momencie, nie zostało ono uruchomione względem bazy danych.

SearchString Jeśli właściwość nie ma wartości null lub jest pusta, zapytanie filmów jest modyfikowane w celu filtrowania w ciągu wyszukiwania:

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

Kod s => s.Title.Contains() jest wyrażeniem lambda. Wyrażenia lambda są używane w zapytaniach LINQ opartych na metodzie jako argumentach do standardowych metod operatorów zapytań, takich jak metoda Where lub Contains. Zapytania LINQ nie są wykonywane podczas ich definiowania lub modyfikacji przez wywołanie metody, takiej jak Where, Containslub OrderBy. Zamiast tego wykonywanie zapytań jest odroczone. Obliczanie wyrażenia jest opóźnione do momentu, aż jego zrealizowana wartość zostanie iterowana lub ToListAsync wywołana metoda. Aby uzyskać więcej informacji, zobacz Wykonywanie zapytań.

Uwaga

Metoda Contains jest uruchamiana w bazie danych, a nie w kodzie języka C#. Ważność wielkości liter w zapytaniu zależy od bazy danych i sortowania. W programie SQL Server Contains mapuje na sql LIKE, co jest bez uwzględniania wielkości liter. SqLite z sortowaniem domyślnym jest kombinacją wielkości liter i wielkości liter w rozróżnianiu w zależności od zapytania. Aby uzyskać informacje na temat tworzenia zapytań SQLite bez uwzględniania wielkości liter, zobacz następujące kwestie:

Przejdź do strony Filmy i dołącz ciąg zapytania, taki jak ?searchString=Ghost adres URL. Na przykład https://localhost:5001/Movies?searchString=Ghost. Zostaną wyświetlone przefiltrowane filmy.

Widok indeksu

Jeśli następujący szablon trasy zostanie dodany do strony Indeks, ciąg wyszukiwania można przekazać jako segment adresu URL. Na przykład https://localhost:5001/Movies/Ghost.

@page "{searchString?}"

Powyższe ograniczenie trasy umożliwia przeszukiwanie tytułu jako danych trasy (segment adresu URL) zamiast jako wartości ciągu zapytania. Wartość ? in "{searchString?}" oznacza, że jest to opcjonalny parametr trasy.

Widok indeksu ze słowem ghost dodanym do adresu URL i zwróconą listą filmów: Ghostbusters i Ghostbusters 2

Środowisko uruchomieniowe ASP.NET Core używa powiązania modelu, aby ustawić wartość SearchString właściwości z ciągu zapytania (?searchString=Ghost) lub danych trasy (https://localhost:5001/Movies/Ghost). Powiązanie modelu nie uwzględnia wielkości liter.

Nie można jednak oczekiwać zmodyfikowania adresu URL w celu wyszukania filmu. W tym kroku interfejs użytkownika jest dodawany do filtrowania filmów. Jeśli dodano ograniczenie "{searchString?}"trasy, usuń go.

Pages/Movies/Index.cshtml Otwórz plik i dodaj znacznik wyróżniony w następującym kodzie:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>

<form>
    <p>
        Title: <input type="text" asp-for="SearchString" />
        <input type="submit" value="Filter" />
    </p>
</form>

<table class="table">
    @*Markup removed for brevity.*@

Tag HTML <form> używa następujących pomocników tagów:

Zapisz zmiany i przetestuj filtr.

Widok indeksu ze słowem ghost wpisanym w polu tekstowym Filtr tytułu

Wyszukiwanie według gatunku

Zaktualizuj metodę strony indeksu OnGetAsync przy użyciu następującego kodu:

public async Task OnGetAsync()
{
    // Use LINQ to get list of genres.
    IQueryable<string> genreQuery = from m in _context.Movie
                                    orderby m.Genre
                                    select m.Genre;

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

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

    if (!string.IsNullOrEmpty(MovieGenre))
    {
        movies = movies.Where(x => x.Genre == MovieGenre);
    }
    Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
    Movie = await movies.ToListAsync();
}

Poniższy kod to zapytanie LINQ, które pobiera wszystkie gatunki z bazy danych.

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

Gatunek SelectList jest tworzony przez projekcję odrębnych gatunków.

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

Dodawanie wyszukiwania według gatunku Razor do strony

Index.cshtml<form>Zaktualizuj element jako wyróżniony w następującym znaczniku:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>

<form>
    <p>
        <select asp-for="MovieGenre" asp-items="Model.Genres">
            <option value="">All</option>
        </select>
        Title: <input type="text" asp-for="SearchString" />
        <input type="submit" value="Filter" />
    </p>
</form>

Przetestuj aplikację, wyszukując według gatunku, według tytułu filmu i obu.

Następne kroki

W poniższych sekcjach dodano wyszukiwanie filmów według gatunku lub nazwy .

Dodaj następujące wyróżnione polecenie przy użyciu instrukcji i właściwości do polecenia Pages/Movies/Index.cshtml.cs:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using RazorPagesMovie.Models;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace RazorPagesMovie.Pages.Movies
{

    public class IndexModel : PageModel
    {
        private readonly RazorPagesMovie.Data.RazorPagesMovieContext _context;

        public IndexModel(RazorPagesMovie.Data.RazorPagesMovieContext context)
        {
            _context = context;
        }

        public IList<Movie> Movie { get; set; }
        [BindProperty(SupportsGet = true)]
        public string SearchString { get; set; }
        public SelectList Genres { get; set; }
        [BindProperty(SupportsGet = true)]
        public string MovieGenre { get; set; }

W poprzednim kodzie:

  • SearchString: zawiera tekst, który użytkownicy wprowadzają w polu tekstowym wyszukiwania. SearchString[BindProperty] ma atrybut . [BindProperty] Wiąże wartości formularza i ciągi zapytania o taką samą nazwę jak właściwość. [BindProperty(SupportsGet = true)] jest wymagany do wiązania żądań HTTP GET.
  • Genres: zawiera listę gatunków. Genres umożliwia użytkownikowi wybranie gatunku z listy. SelectList Wymaga using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre: zawiera określony gatunek wybierany przez użytkownika. Na przykład "Western".
  • Genres i MovieGenre są używane w dalszej części tego samouczka.

Ostrzeżenie

Ze względów bezpieczeństwa należy wyrazić zgodę na powiązanie danych żądania GET z właściwościami modelu strony. Przed mapowaniem danych wejściowych użytkownika na właściwości zweryfikuj je. Wyrażenie zgody na powiązanie danych GET jest przydatne w scenariuszach, które wykorzystują ciągi zapytania lub wartości trasy.

Aby powiązać właściwość w przypadku żądań GET, ustaw właściwość SupportsGet atrybutu [BindProperty] na true:

[BindProperty(SupportsGet = true)]

Aby uzyskać więcej informacji, zobacz Podsumowanie ASP.NET Core Community Standup: dyskusja na temat powiązania z użyciem metody GET (YouTube).

Zaktualizuj metodę strony indeksu OnGetAsync przy użyciu następującego kodu:

public async Task OnGetAsync()
{
    var movies = from m in _context.Movie
                 select m;
    if (!string.IsNullOrEmpty(SearchString))
    {
        movies = movies.Where(s => s.Title.Contains(SearchString));
    }

    Movie = await movies.ToListAsync();
}

Pierwszy wiersz OnGetAsync metody tworzy zapytanie LINQ w celu wybrania filmów:

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

Zapytanie jest zdefiniowane tylko w tym momencie, nie zostało ono uruchomione względem bazy danych.

SearchString Jeśli właściwość nie ma wartości null lub jest pusta, zapytanie filmów jest modyfikowane w celu filtrowania w ciągu wyszukiwania:

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

Kod s => s.Title.Contains() jest wyrażeniem lambda. Wyrażenia lambda są używane w zapytaniach LINQ opartych na metodzie jako argumentach do standardowych metod operatorów zapytań, takich jak metoda Where lub Contains. Zapytania LINQ nie są wykonywane podczas ich definiowania lub modyfikacji przez wywołanie metody, takiej jak Where, Containslub OrderBy. Zamiast tego wykonywanie zapytań jest odroczone. Obliczanie wyrażenia jest opóźnione do momentu, aż jego zrealizowana wartość zostanie iterowana lub ToListAsync wywołana metoda. Aby uzyskać więcej informacji, zobacz Wykonywanie zapytań.

Uwaga

Metoda Contains jest uruchamiana w bazie danych, a nie w kodzie języka C#. Ważność wielkości liter w zapytaniu zależy od bazy danych i sortowania. W programie SQL Server Contains mapuje na sql LIKE, co jest bez uwzględniania wielkości liter. SqLite z sortowaniem domyślnym jest kombinacją wielkości liter i wielkości liter w rozróżnianiu w zależności od zapytania. Aby uzyskać informacje na temat tworzenia zapytań SQLite bez uwzględniania wielkości liter, zobacz następujące kwestie:

Przejdź do strony Filmy i dołącz ciąg zapytania, taki jak ?searchString=Ghost adres URL. Na przykład https://localhost:5001/Movies?searchString=Ghost. Zostaną wyświetlone przefiltrowane filmy.

Widok indeksu

Jeśli następujący szablon trasy zostanie dodany do strony Indeks, ciąg wyszukiwania można przekazać jako segment adresu URL. Na przykład https://localhost:5001/Movies/Ghost.

@page "{searchString?}"

Powyższe ograniczenie trasy umożliwia przeszukiwanie tytułu jako danych trasy (segment adresu URL) zamiast jako wartości ciągu zapytania. Wartość ? in "{searchString?}" oznacza, że jest to opcjonalny parametr trasy.

Widok indeksu ze słowem ghost dodanym do adresu URL i zwróconą listą filmów: Ghostbusters i Ghostbusters 2

Środowisko uruchomieniowe ASP.NET Core używa powiązania modelu, aby ustawić wartość SearchString właściwości z ciągu zapytania (?searchString=Ghost) lub danych trasy (https://localhost:5001/Movies/Ghost). Powiązanie modelu nie uwzględnia wielkości liter.

Nie można jednak oczekiwać zmodyfikowania adresu URL w celu wyszukania filmu. W tym kroku interfejs użytkownika jest dodawany do filtrowania filmów. Jeśli dodano ograniczenie "{searchString?}"trasy, usuń go.

Pages/Movies/Index.cshtml Otwórz plik i dodaj znacznik wyróżniony w następującym kodzie:

@page
@model RazorPagesMovie.Pages.Movies.IndexModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>

<form>
    <p>
        Title: <input type="text" asp-for="SearchString" />
        <input type="submit" value="Filter" />
    </p>
</form>

<table class="table">
    @*Markup removed for brevity.*@

Tag HTML <form> używa następujących pomocników tagów:

Zapisz zmiany i przetestuj filtr.

Widok indeksu ze słowem ghost wpisanym w polu tekstowym Filtr tytułu

Wyszukiwanie według gatunku

Zaktualizuj metodę strony indeksu OnGetAsync przy użyciu następującego kodu:

public async Task OnGetAsync()
{
    // Use LINQ to get list of genres.
    IQueryable<string> genreQuery = from m in _context.Movie
                                    orderby m.Genre
                                    select m.Genre;

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

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

    if (!string.IsNullOrEmpty(MovieGenre))
    {
        movies = movies.Where(x => x.Genre == MovieGenre);
    }
    Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
    Movie = await movies.ToListAsync();
}

Poniższy kod to zapytanie LINQ, które pobiera wszystkie gatunki z bazy danych.

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

Gatunek SelectList jest tworzony przez projekcję odrębnych gatunków.

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

Dodawanie wyszukiwania według gatunku Razor do strony

  1. Index.cshtml<form>Zaktualizuj element jako wyróżniony w następującym znaczniku:

    @page
    @model RazorPagesMovie.Pages.Movies.IndexModel
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <p>
        <a asp-page="Create">Create New</a>
    </p>
    
    <form>
        <p>
            <select asp-for="MovieGenre" asp-items="Model.Genres">
                <option value="">All</option>
            </select>
            Title: <input type="text" asp-for="SearchString" />
            <input type="submit" value="Filter" />
        </p>
    </form>
    
    <table class="table">
        @*Markup removed for brevity.*@
    
    
  2. Przetestuj aplikację, wyszukując według gatunku, według tytułu filmu i obu.

Następne kroki