bölüm 6, ASP.NET Core sayfalara arama ekleme Razor

Gönderen Rick Anderson

Aşağıdaki bölümlerde, film tarzya veya ada göre arama eklenir.

Aşağıdaki Vurgulanan kodu sayfalara/filmlere/ Index . cshtml. cs öğesine ekleyin:

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

Önceki kodda:

  • SearchString: Kullanıcılar arama metin kutusuna girdiğiniz metni içerir. SearchString özniteliği vardır [BindProperty] . [BindProperty] Form değerlerini ve Sorgu dizelerini özelliği ile aynı ada bağlar. [BindProperty(SupportsGet = true)] HTTP GET isteklerinde bağlama için gereklidir.
  • Genres: Tarzlar listesini içerir. Genres kullanıcının listeden bir tarz seçmesine izin verir. SelectList gerektirmeyen using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre: Kullanıcının seçtiği belirli tarzı içerir. Örneğin, "Batı".
  • Genres ve MovieGenre Bu öğreticide daha sonra kullanılır.

Uyarı

Güvenlik nedeniyle, istek verilerini sayfa modeli GET özelliklerine bağlamayı kabul edebilirsiniz. Kullanıcı girişini özelliklere eşlemeden önce doğrulayın. Bağlamayı GET kabul etmek, sorgu dizesi veya yol değerlerine bağlı senaryoları ele almak için kullanışlıdır.

İsteklerde bir özelliği GET bağlamak için [BindProperty] özniteliğin özelliğini olarak SupportsGet true ayarlayın:

[BindProperty(SupportsGet = true)]

Daha fazla bilgi için bkz. ASP.NET Çekirdek Topluluk Standup: GET tartışmalarını bağlama (YouTube).

IndexSayfanın OnGetAsync yöntemini aşağıdaki kodla güncelleştirin:

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

Yöntemin ilk satırı, OnGetAsync filmleri seçmek için bir LINQ sorgusu oluşturur:

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

Sorgu yalnızca tanımlı _ Bu noktada, veritabanında _ Not çalıştırılmadı.

SearchStringÖzellik null veya boş değilse, filmler sorgusu arama dizesinde filtrelenecek şekilde değiştirilir:

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

s => s.Title.Contains()Kod bir lambda ifadesidir. Lambdalar, Yöntem tabanlı LINQ sorgularında, WHERE yöntemi veya gibi standart sorgu işleci yöntemlerine bağımsız değişkenler olarak kullanılır Contains . LINQ sorguları tanımlandıklarında veya, ya da gibi bir yöntem çağırarak değiştirildiklerinde yürütülmez Where Contains OrderBy . Bunun yerine sorgu yürütmesi ertelenir. Bir ifadenin değerlendirilmesi, gerçekleştirilmiş değeri yinelenene veya ToListAsync Yöntem çağrılana kadar gecikiyor. Daha fazla bilgi için bkz. sorgu yürütme .

Not

Contains yöntemi C# kodunda değil veritabanında çalıştırılır. Sorgudaki büyük/küçük harf duyarlılığı veritabanına ve harmanlamaya bağlıdır. SQL Server, Contains büyük/küçük harfe duyarsız olacak şekilde SQLeşlenir. Varsayılan harmanlamaya sahip SQLite, sorguya bağlı olarak büyük/küçük harfe duyarlı ve büyük/küçük harfe duyarlı bir karışımdır. Büyük/küçük harfe duyarsız SQLite sorguları yapma hakkında bilgi için aşağıdakilere bakın:

Filmler sayfasına gidin ve URL 'ye gibi bir sorgu dizesi ekleyin ?searchString=Ghost . Örneğin, https://localhost:5001/Movies?searchString=Ghost. Filtrelenmiş filmler görüntülenir.

::: No-Loc (Dizin)::: görünüm

Aşağıdaki yol şablonu Index sayfaya eklenirse, arama dizesi BIR URL segmenti olarak geçirilebilir. Örneğin, https://localhost:5001/Movies/Ghost.

@page "{searchString?}"

Önceki yol kısıtlaması, başlığın sorgu dizesi değeri yerine rota verileri (bir URL segmenti) olarak aranmasına olanak tanır. ?İçinde "{searchString?}" bunun isteğe bağlı bir yol parametresi olduğu anlamına gelir.

::: No-Loc (Dizin)::: URL 'ye eklenen ve iki filmde döndürülen bir film listesi, Ghostbusters ve Ghostbusters ve 2

ASP.NET Core çalışma zamanı, SearchString özelliğin değerini sorgu dizesinden ( ?searchString=Ghost ) veya rota verilerinden () ayarlamak için model bağlamayı kullanır https://localhost:5001/Movies/Ghost . Model bağlama büyük/küçük harfe duyarlı değildir .

Ancak, kullanıcıların bir filmi aramak için URL 'YI değiştirmesi beklenmez. Bu adımda, filmleri filtrelemek için Kullanıcı arabirimi eklenir. Yol kısıtlaması eklediyseniz "{searchString?}" , kaldırın.

Pages/filmler/ Index . cshtml dosyasını açın ve aşağıdaki kodda vurgulanan biçimlendirmeyi ekleyin:

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

HTML <form> etiketi aşağıdaki Etiket Yardımcılarıkullanır:

Değişiklikleri kaydedin ve filtreyi test edin.

::: No-Loc (Dizin)::: başlık filtresi metin kutusuna hayalet sözcük türü görüntüle

Tarza göre ara

IndexSayfanın OnGetAsync yöntemini aşağıdaki kodla güncelleştirin:

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

Aşağıdaki kod, veritabanından tüm tarzları alan bir LINQ sorgusudur.

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

SelectListTarzlar, farklı tarzlar yansıtılayarak oluşturulur.

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

Sayfaya türe göre ara ekleme Razor

Index . Cshtml <form> öğesini aşağıdaki biçimlendirmede vurgulanan şekilde güncelleştirin:

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

Türe göre, film başlığına göre ve her ikisine birden arayarak uygulamayı test edin.

Aşağıdaki bölümlerde, film tarzya veya ada göre arama eklenir.

Aşağıdaki Vurgulanan using ifadesini ve özelliklerini Pages/filmler/ Index . cshtml. cs öğesine ekleyin:

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

Önceki kodda:

  • SearchString: Kullanıcılar arama metin kutusuna girdiğiniz metni içerir. SearchString özniteliği vardır [BindProperty] . [BindProperty] Form değerlerini ve Sorgu dizelerini özelliği ile aynı ada bağlar. [BindProperty(SupportsGet = true)] HTTP GET isteklerinde bağlama için gereklidir.
  • Genres: Tarzlar listesini içerir. Genres kullanıcının listeden bir tarz seçmesine izin verir. SelectList gerektirmeyen using Microsoft.AspNetCore.Mvc.Rendering;
  • MovieGenre: Kullanıcının seçtiği belirli tarzı içerir. Örneğin, "Batı".
  • Genres ve MovieGenre Bu öğreticide daha sonra kullanılır.

Uyarı

Güvenlik nedeniyle, istek verilerini sayfa modeli GET özelliklerine bağlamayı kabul edebilirsiniz. Kullanıcı girişini özelliklere eşlemeden önce doğrulayın. Bağlamayı GET kabul etmek, sorgu dizesi veya yol değerlerine bağlı senaryoları ele almak için kullanışlıdır.

İsteklerde bir özelliği GET bağlamak için [BindProperty] özniteliğin özelliğini olarak SupportsGet true ayarlayın:

[BindProperty(SupportsGet = true)]

Daha fazla bilgi için bkz. ASP.NET Çekirdek Topluluk Standup: GET tartışmalarını bağlama (YouTube).

IndexSayfanın OnGetAsync yöntemini aşağıdaki kodla güncelleştirin:

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

Yöntemin ilk satırı, OnGetAsync filmleri seçmek için bir LINQ sorgusu oluşturur:

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

Sorgu yalnızca tanımlı _ Bu noktada, veritabanında _ Not çalıştırılmadı.

SearchStringÖzellik null veya boş değilse, filmler sorgusu arama dizesinde filtrelenecek şekilde değiştirilir:

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

s => s.Title.Contains()Kod bir lambda ifadesidir. Lambdalar, Yöntem tabanlı LINQ sorgularında, WHERE yöntemi veya gibi standart sorgu işleci yöntemlerine bağımsız değişkenler olarak kullanılır Contains . LINQ sorguları tanımlandıklarında veya, ya da gibi bir yöntem çağırarak değiştirildiklerinde yürütülmez Where Contains OrderBy . Bunun yerine sorgu yürütmesi ertelenir. Bir ifadenin değerlendirilmesi, gerçekleştirilmiş değeri yinelenene veya ToListAsync Yöntem çağrılana kadar gecikiyor. Daha fazla bilgi için bkz. sorgu yürütme .

Not

Contains yöntemi C# kodunda değil veritabanında çalıştırılır. Sorgudaki büyük/küçük harf duyarlılığı veritabanına ve harmanlamaya bağlıdır. SQL Server, Contains büyük/küçük harfe duyarsız olacak şekilde SQLeşlenir. Varsayılan harmanlamaya sahip SQLite, sorguya bağlı olarak büyük/küçük harfe duyarlı ve büyük/küçük harfe duyarlı bir karışımdır. Büyük/küçük harfe duyarsız SQLite sorguları yapma hakkında bilgi için aşağıdakilere bakın:

Filmler sayfasına gidin ve URL 'ye gibi bir sorgu dizesi ekleyin ?searchString=Ghost . Örneğin, https://localhost:5001/Movies?searchString=Ghost. Filtrelenmiş filmler görüntülenir.

::: No-Loc (Dizin)::: görünüm

Aşağıdaki yol şablonu Index sayfaya eklenirse, arama dizesi BIR URL segmenti olarak geçirilebilir. Örneğin, https://localhost:5001/Movies/Ghost.

@page "{searchString?}"

Yukarıdaki yol kısıtlaması, başlığın sorgu dizesi değeri yerine rota verileri (URL segmenti) olarak aramasını sağlar. ?in, "{searchString?}" bunun isteğe bağlı bir yol parametresi olduğu anlamına gelir.

Index url'ye ghost sözcüğü ekli ve iki filmden (Ghostbusters ve Ghostbusters 2) döndürülen bir film listesiyle görünüm

Bu ASP.NET Core çalışma zamanı, sorgu dizesinden ( ) veya yol verilerinden ( ) özelliğinin değerini ayarlamak için model SearchString ?searchString=Ghost bağlamasını https://localhost:5001/Movies/Ghost kullanır. Model bağlaması büyük/büyük/büyük harfe duyarlı değildir.

Ancak kullanıcıların BIR film aramak için URL'yi değiştirmesi beklenmiyor. Bu adımda, film filtrelemek için kullanıcı arabirimi eklenir. Yol kısıtlamasını "{searchString?}" eklediysanız kaldırın.

Pages/Movies/ Index .cshtml dosyasını açın ve aşağıdaki kodda vurgulanan işaretlemeyi ekleyin:

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

HTML <form> etiketi aşağıdaki Etiket Yardımcılarını kullanır:

Değişiklikleri kaydedin ve filtreyi test etmek.

Index başlık filtresi metin kutusuna ghost sözcüğüyle görünüm

Türe göre arama

Sayfanın Index yöntemini aşağıdaki OnGetAsync kodla güncelleştirin:

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

Aşağıdaki kod, veritabanından tüm türleri alan bir LINQ sorgusudur.

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

Türlerin SelectList türü, ayrı türler proje oluşturularak oluşturulur.

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

Sayfaya türe göre arama Razor ekleme

  1. Index .cshtml öğesini <form> aşağıdaki işaretlemede vurgulanan şekilde güncelleştirin:

    @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. Türe, film başlığına ve her iki türüne göre arayarak uygulamayı test edin.

Ek kaynaklar