Nota
L'accesso a questa pagina richiede l'autorizzazione. Puoi provare ad accedere o a cambiare directory.
L'accesso a questa pagina richiede l'autorizzazione. Puoi provare a cambiare directory.
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 10 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere i criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 10 di questo articolo.
Nelle sezioni seguenti viene aggiunta la funzionalità di ricerca di film in base al genere oppure al nome.
Aggiungere il codice evidenziato seguente a 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; }
Nel codice precedente:
-
SearchString: contiene il testo immesso dagli utenti nella casella di testo di ricerca.SearchStringha l'attributo[BindProperty].[BindProperty]associa i valori modulo e le stringhe di query al nome della proprietà.[BindProperty(SupportsGet = true)]è obbligatorio per l'associazione nelle richieste HTTP GET. -
Genres: contiene l'elenco dei generi.Genresconsente all'utente di selezionare un genere dall'elenco.SelectListrichiedeusing Microsoft.AspNetCore.Mvc.Rendering; -
MovieGenre: contiene il genere specifico selezionato dall'utente. Ad esempio, "Western". -
GenreseMovieGenresono utilizzati più avanti in questa esercitazione.
Avviso
Per motivi di sicurezza, è necessario acconsentire esplicitamente all'associazione dei dati della richiesta GET alle proprietà del modello di pagina. Verificare l'input dell'utente prima di eseguirne il mapping alle proprietà. Acconsentire esplicitamente all'associazione GET è utile in scenari basati su valori route o stringa di query.
Per associare una proprietà nelle richieste GET, impostare la proprietà [BindProperty] dell'attributo SupportsGet su true:
[BindProperty(SupportsGet = true)]
Per altre informazioni, vedere ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Aggiornare il Movies/Index metodo della OnGetAsync pagina con il codice seguente:
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();
}
La prima riga del metodo OnGetAsync crea una query LINQ per selezionare i film:
var movies = from m in _context.Movie
select m;
La query viene solo definita in questo punto, ma non viene eseguita nel database.
Se la SearchString proprietà non null è o vuota, la query movies viene modificata per filtrare la stringa di ricerca:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Il codice s => s.Title.Contains() è un'espressione lambda. Le espressioni lambda vengono usate nelle query LINQ basate su metodo come argomenti per metodi dell'operatore di query standard, ad esempio il metodo Where o Contains. Le query LINQ non vengono eseguite quando vengono definite o quando vengono modificate chiamando un metodo, ad esempio Where, Containso OrderBy. L'esecuzione della query viene invece posticipata. La valutazione di un'espressione viene ritardata fino a quando non viene eseguito l'iterazione del relativo valore realizzato o viene chiamato il ToListAsync metodo . Per altre informazioni, vedere Esecuzione di query.
Nota
Il Contains metodo viene eseguito nel database, non nel codice C#. La distinzione tra maiuscole/minuscole nella query dipende dal database e dalle regole di confronto. In SQL Server Contains esegue il mapping a SQL LIKE che fa distinzione tra maiuscole e minuscole. SQLite con le regole di confronto predefinite è una combinazione di distinzione tra maiuscole e minuscole e di distinzione tra maiuscole e minuscole, a seconda della query. Per informazioni sull'esecuzione di query SQLite senza distinzione tra maiuscole e minuscole, vedere quanto segue:
Passare alla pagina Film e aggiungere una stringa di query, ?searchString=Ghost ad esempio all'URL. Ad esempio: https://localhost:5001/Movies?searchString=Ghost. Vengono visualizzati i film filtrati.
Se il modello di route seguente viene aggiunto alla pagina Indice, la stringa di ricerca può essere passata come segmento di URL. Ad esempio: https://localhost:5001/Movies/Ghost.
@page "{searchString?}"
Il vincolo di route precedente consente la ricerca del titolo come dati della route (un segmento URL), anziché come valore della stringa di query. Il carattere ? in "{searchString?}" indica che questo parametro di route è facoltativo.
Il runtime di ASP.NET Core usa l'associazione di modelli per impostare il valore della proprietà SearchString dalla stringa di query (?searchString=Ghost) o dai dati della route (https://localhost:5001/Movies/Ghost). L'associazione di modelli non fa distinzione tra maiuscole e minuscole.
Tuttavia, non è previsto che gli utenti modifichino l'URL per cercare un filmato. In questo passaggio viene aggiunta l'interfaccia utente per filtrare i film. Rimuovere il vincolo di route "{searchString?}", se è stato aggiunto.
Aprire il Pages/Movies/Index.cshtml file e aggiungere il markup evidenziato nel codice seguente:
@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>
Il tag HTML <form> usa gli helper tag seguenti:
- Helper tag Form. Quando il modulo viene inviato, la stringa di filtro verrà inviata alla pagina Pages/Movies/Index tramite una stringa di query.
- Helper per tag di input
Salvare le modifiche e testare il filtro.
Ricerca in base al genere
Aggiornare il Movies/Index.cshtml.cs metodo page OnGetAsync con il codice seguente:
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();
}
Il codice seguente è una query LINQ che recupera tutti i generi dal database.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
Il SelectList di genere viene creato proiettando i generi distinti:
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Aggiungere la ricerca per genere alla Razor pagina
Aggiornare l'elemento Index.cshtml<form> come evidenziato nel markup seguente:
@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>
Eseguire il test dell'app effettuando una ricerca per genere, titolo del film ed entrambi:
Passaggi successivi
Nelle sezioni seguenti viene aggiunta la funzionalità di ricerca di film in base al genere oppure al nome.
Aggiungere il codice evidenziato seguente a 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; }
Nel codice precedente:
-
SearchString: contiene il testo immesso dagli utenti nella casella di testo di ricerca.SearchStringha l'attributo[BindProperty].[BindProperty]associa i valori modulo e le stringhe di query al nome della proprietà.[BindProperty(SupportsGet = true)]è obbligatorio per l'associazione nelle richieste HTTP GET. -
Genres: contiene l'elenco dei generi.Genresconsente all'utente di selezionare un genere dall'elenco.SelectListrichiedeusing Microsoft.AspNetCore.Mvc.Rendering; -
MovieGenre: contiene il genere specifico selezionato dall'utente. Ad esempio, "Western". -
GenreseMovieGenresono utilizzati più avanti in questa esercitazione.
Avviso
Per motivi di sicurezza, è necessario acconsentire esplicitamente all'associazione dei dati della richiesta GET alle proprietà del modello di pagina. Verificare l'input dell'utente prima di eseguirne il mapping alle proprietà. Acconsentire esplicitamente all'associazione GET è utile in scenari basati su valori route o stringa di query.
Per associare una proprietà nelle richieste GET, impostare la proprietà [BindProperty] dell'attributo SupportsGet su true:
[BindProperty(SupportsGet = true)]
Per altre informazioni, vedere ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Aggiornare il metodo OnGetAsync della pagina di indice con il codice seguente:
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();
}
La prima riga del metodo OnGetAsync crea una query LINQ per selezionare i film:
// using System.Linq;
var movies = from m in _context.Movie
select m;
La query viene solo definita in questo punto, ma non viene eseguita nel database.
Se la SearchString proprietà non null è o vuota, la query movies viene modificata per filtrare la stringa di ricerca:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Il codice s => s.Title.Contains() è un'espressione lambda. Le espressioni lambda vengono usate nelle query LINQ basate su metodo come argomenti per metodi dell'operatore di query standard, ad esempio il metodo Where o Contains. Le query LINQ non vengono eseguite quando vengono definite o quando vengono modificate chiamando un metodo, ad esempio Where, Containso OrderBy. L'esecuzione della query viene invece posticipata. La valutazione di un'espressione viene ritardata fino a quando non viene eseguito l'iterazione del relativo valore realizzato o viene chiamato il ToListAsync metodo . Per altre informazioni, vedere Esecuzione di query.
Nota
Il Contains metodo viene eseguito nel database, non nel codice C#. La distinzione tra maiuscole/minuscole nella query dipende dal database e dalle regole di confronto. In SQL Server Contains esegue il mapping a SQL LIKE che fa distinzione tra maiuscole e minuscole. SQLite con le regole di confronto predefinite è una combinazione di distinzione tra maiuscole e minuscole e di distinzione tra maiuscole e minuscole, a seconda della query. Per informazioni sull'esecuzione di query SQLite senza distinzione tra maiuscole e minuscole, vedere quanto segue:
Passare alla pagina Film e aggiungere una stringa di query, ?searchString=Ghost ad esempio all'URL. Ad esempio: https://localhost:5001/Movies?searchString=Ghost. Vengono visualizzati i film filtrati.
Se il modello di route seguente viene aggiunto alla pagina Indice, la stringa di ricerca può essere passata come segmento di URL. Ad esempio: https://localhost:5001/Movies/Ghost.
@page "{searchString?}"
Il vincolo di route precedente consente la ricerca del titolo come dati della route (un segmento URL), anziché come valore della stringa di query. Il carattere ? in "{searchString?}" indica che questo parametro di route è facoltativo.
Il runtime di ASP.NET Core usa l'associazione di modelli per impostare il valore della proprietà SearchString dalla stringa di query (?searchString=Ghost) o dai dati della route (https://localhost:5001/Movies/Ghost). L'associazione di modelli non fa distinzione tra maiuscole e minuscole.
Tuttavia, non è previsto che gli utenti modifichino l'URL per cercare un filmato. In questo passaggio viene aggiunta l'interfaccia utente per filtrare i film. Rimuovere il vincolo di route "{searchString?}", se è stato aggiunto.
Aprire il Pages/Movies/Index.cshtml file e aggiungere il markup evidenziato nel codice seguente:
@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.*@
Il tag HTML <form> usa gli helper tag seguenti:
- Helper tag Form. Quando il modulo viene inviato, la stringa di filtro verrà inviata alla pagina Pages/Movies/Index tramite una stringa di query.
- Helper per tag di input
Salvare le modifiche e testare il filtro.
Ricerca in base al genere
Aggiornare il Movies/Index.cshtml.cs metodo page OnGetAsync con il codice seguente:
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();
}
Il codice seguente è una query LINQ che recupera tutti i generi dal database.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
L'elenco SelectList di generi viene creato selezionando generi distinti.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Aggiungere la ricerca per genere alla Razor pagina
Aggiornare l'elemento Index.cshtml<form> come evidenziato nel markup seguente:
@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>
Eseguire il test dell'app effettuando una ricerca per genere, titolo del film e usando entrambi i filtri.
Passaggi successivi
Nelle sezioni seguenti viene aggiunta la funzionalità di ricerca di film in base al genere oppure al nome.
Aggiungere il codice evidenziato seguente a 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; }
Nel codice precedente:
-
SearchString: contiene il testo immesso dagli utenti nella casella di testo di ricerca.SearchStringha l'attributo[BindProperty].[BindProperty]associa i valori modulo e le stringhe di query al nome della proprietà.[BindProperty(SupportsGet = true)]è obbligatorio per l'associazione nelle richieste HTTP GET. -
Genres: contiene l'elenco dei generi.Genresconsente all'utente di selezionare un genere dall'elenco.SelectListrichiedeusing Microsoft.AspNetCore.Mvc.Rendering; -
MovieGenre: contiene il genere specifico selezionato dall'utente. Ad esempio, "Western". -
GenreseMovieGenresono utilizzati più avanti in questa esercitazione.
Avviso
Per motivi di sicurezza, è necessario acconsentire esplicitamente all'associazione dei dati della richiesta GET alle proprietà del modello di pagina. Verificare l'input dell'utente prima di eseguirne il mapping alle proprietà. Acconsentire esplicitamente all'associazione GET è utile in scenari basati su valori route o stringa di query.
Per associare una proprietà nelle richieste GET, impostare la proprietà [BindProperty] dell'attributo SupportsGet su true:
[BindProperty(SupportsGet = true)]
Per altre informazioni, vedere ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Aggiornare il metodo OnGetAsync della pagina di indice con il codice seguente:
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();
}
La prima riga del metodo OnGetAsync crea una query LINQ per selezionare i film:
// using System.Linq;
var movies = from m in _context.Movie
select m;
La query viene solo definita in questo punto, ma non viene eseguita nel database.
Se la SearchString proprietà non null è o vuota, la query movies viene modificata per filtrare la stringa di ricerca:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Il codice s => s.Title.Contains() è un'espressione lambda. Le espressioni lambda vengono usate nelle query LINQ basate su metodo come argomenti per metodi dell'operatore di query standard, ad esempio il metodo Where o Contains. Le query LINQ non vengono eseguite quando vengono definite o quando vengono modificate chiamando un metodo, ad esempio Where, Containso OrderBy. L'esecuzione della query viene invece posticipata. La valutazione di un'espressione viene ritardata fino a quando non viene eseguito l'iterazione del relativo valore realizzato o viene chiamato il ToListAsync metodo . Per altre informazioni, vedere Esecuzione di query.
Nota
Il Contains metodo viene eseguito nel database, non nel codice C#. La distinzione tra maiuscole/minuscole nella query dipende dal database e dalle regole di confronto. In SQL Server Contains esegue il mapping a SQL LIKE che fa distinzione tra maiuscole e minuscole. SQLite con le regole di confronto predefinite è una combinazione di distinzione tra maiuscole e minuscole e di distinzione tra maiuscole e minuscole, a seconda della query. Per informazioni sull'esecuzione di query SQLite senza distinzione tra maiuscole e minuscole, vedere quanto segue:
- Questo problema di GitHub
- Questo problema di GitHub
- Regole di confronto e distinzione tra maiuscole e minuscole
Passare alla pagina Film e aggiungere una stringa di query, ?searchString=Ghost ad esempio all'URL. Ad esempio: https://localhost:5001/Movies?searchString=Ghost. Vengono visualizzati i film filtrati.
Se il modello di route seguente viene aggiunto alla pagina Indice, la stringa di ricerca può essere passata come segmento di URL. Ad esempio: https://localhost:5001/Movies/Ghost.
@page "{searchString?}"
Il vincolo di route precedente consente la ricerca del titolo come dati della route (un segmento URL), anziché come valore della stringa di query. Il carattere ? in "{searchString?}" indica che questo parametro di route è facoltativo.
Il runtime di ASP.NET Core usa l'associazione di modelli per impostare il valore della proprietà SearchString dalla stringa di query (?searchString=Ghost) o dai dati della route (https://localhost:5001/Movies/Ghost). L'associazione di modelli non fa distinzione tra maiuscole e minuscole.
Tuttavia, non è previsto che gli utenti modifichino l'URL per cercare un filmato. In questo passaggio viene aggiunta l'interfaccia utente per filtrare i film. Rimuovere il vincolo di route "{searchString?}", se è stato aggiunto.
Aprire il Pages/Movies/Index.cshtml file e aggiungere il markup evidenziato nel codice seguente:
@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.*@
Il tag HTML <form> usa gli helper tag seguenti:
- Helper tag Form. Quando il modulo viene inviato, la stringa di filtro verrà inviata alla pagina Pages/Movies/Index tramite una stringa di query.
- Helper per tag di input
Salvare le modifiche e testare il filtro.
Ricerca in base al genere
Aggiornare il metodo OnGetAsync della pagina di indice con il codice seguente:
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();
}
Il codice seguente è una query LINQ che recupera tutti i generi dal database.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
L'elenco SelectList di generi viene creato selezionando generi distinti.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Aggiungere la ricerca per genere alla Razor pagina
Aggiornare l'elemento Index.cshtml<form> come evidenziato nel markup seguente:
@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>
Eseguire il test dell'app effettuando una ricerca per genere, titolo del film e usando entrambi i filtri.
Passaggi successivi
Nelle sezioni seguenti viene aggiunta la funzionalità di ricerca di film in base al genere oppure al nome.
Aggiungere il codice evidenziato seguente a 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; }
Nel codice precedente:
-
SearchString: contiene il testo immesso dagli utenti nella casella di testo di ricerca.SearchStringha l'attributo[BindProperty].[BindProperty]associa i valori modulo e le stringhe di query al nome della proprietà.[BindProperty(SupportsGet = true)]è obbligatorio per l'associazione nelle richieste HTTP GET. -
Genres: contiene l'elenco dei generi.Genresconsente all'utente di selezionare un genere dall'elenco.SelectListrichiedeusing Microsoft.AspNetCore.Mvc.Rendering; -
MovieGenre: contiene il genere specifico selezionato dall'utente. Ad esempio, "Western". -
GenreseMovieGenresono utilizzati più avanti in questa esercitazione.
Avviso
Per motivi di sicurezza, è necessario acconsentire esplicitamente all'associazione dei dati della richiesta GET alle proprietà del modello di pagina. Verificare l'input dell'utente prima di eseguirne il mapping alle proprietà. Acconsentire esplicitamente all'associazione GET è utile in scenari basati su valori route o stringa di query.
Per associare una proprietà nelle richieste GET, impostare la proprietà [BindProperty] dell'attributo SupportsGet su true:
[BindProperty(SupportsGet = true)]
Per altre informazioni, vedere ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Aggiornare il metodo OnGetAsync della pagina di indice con il codice seguente:
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();
}
La prima riga del metodo OnGetAsync crea una query LINQ per selezionare i film:
// using System.Linq;
var movies = from m in _context.Movie
select m;
La query viene solo definita in questo punto, ma non viene eseguita nel database.
Se la proprietà SearchString non è null o vuota, la query dei film viene modificata per filtrare gli elementi in base alla stringa di ricerca:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Il codice s => s.Title.Contains() è un'espressione lambda. Le espressioni lambda vengono usate nelle query LINQ basate su metodo come argomenti per metodi dell'operatore di query standard, ad esempio il metodo Where o Contains. Le query LINQ non vengono eseguite quando vengono definite o quando vengono modificate chiamando un metodo, ad esempio Where, Containso OrderBy. L'esecuzione della query viene invece posticipata. La valutazione di un'espressione viene ritardata fino a quando non viene eseguito l'iterazione del relativo valore realizzato o viene chiamato il ToListAsync metodo . Per altre informazioni, vedere Esecuzione di query.
Nota
Il Contains metodo viene eseguito nel database, non nel codice C#. La distinzione tra maiuscole/minuscole nella query dipende dal database e dalle regole di confronto. In SQL Server Contains esegue il mapping a SQL LIKE che fa distinzione tra maiuscole e minuscole. SQLite con le regole di confronto predefinite è una combinazione di distinzione tra maiuscole e minuscole e di distinzione tra maiuscole e minuscole, a seconda della query. Per informazioni sull'esecuzione di query SQLite senza distinzione tra maiuscole e minuscole, vedere quanto segue:
- Questo problema di GitHub
- Questo problema di GitHub
- Regole di confronto e distinzione tra maiuscole e minuscole
Passare alla pagina Film e aggiungere una stringa di query, ?searchString=Ghost ad esempio all'URL. Ad esempio: https://localhost:5001/Movies?searchString=Ghost. Vengono visualizzati i film filtrati.
Se il modello di route seguente viene aggiunto alla pagina Indice, la stringa di ricerca può essere passata come segmento di URL. Ad esempio: https://localhost:5001/Movies/Ghost.
@page "{searchString?}"
Il vincolo di route precedente consente la ricerca del titolo come dati della route (un segmento URL), anziché come valore della stringa di query. Il carattere ? in "{searchString?}" indica che questo parametro di route è facoltativo.
Il runtime di ASP.NET Core usa l'associazione di modelli per impostare il valore della proprietà SearchString dalla stringa di query (?searchString=Ghost) o dai dati della route (https://localhost:5001/Movies/Ghost). L'associazione di modelli non fa distinzione tra maiuscole e minuscole.
Tuttavia, non è previsto che gli utenti modifichino l'URL per cercare un filmato. In questo passaggio viene aggiunta l'interfaccia utente per filtrare i film. Rimuovere il vincolo di route "{searchString?}", se è stato aggiunto.
Aprire il Pages/Movies/Index.cshtml file e aggiungere il markup evidenziato nel codice seguente:
@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.*@
Il tag HTML <form> usa gli helper tag seguenti:
- Helper tag Form. Quando il modulo viene inviato, la stringa di filtro verrà inviata alla pagina Pages/Movies/Index tramite una stringa di query.
- Helper per tag di input
Salvare le modifiche e testare il filtro.
Ricerca in base al genere
Aggiornare il metodo OnGetAsync della pagina di indice con il codice seguente:
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();
}
Il codice seguente è una query LINQ che recupera tutti i generi dal database.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
L'elenco SelectList di generi viene creato selezionando generi distinti.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Aggiungere la ricerca per genere alla Razor pagina
Aggiornare l'elemento Index.cshtml<form> come evidenziato nel markup seguente:
@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>
Eseguire il test dell'app effettuando una ricerca per genere, titolo del film e usando entrambi i filtri.
Passaggi successivi
Nelle sezioni seguenti viene aggiunta la funzionalità di ricerca di film in base al genere oppure al nome.
Aggiungere le proprietà e l'istruzione using seguenti evidenziate a 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; }
Nel codice precedente:
-
SearchString: contiene il testo immesso dagli utenti nella casella di testo di ricerca.SearchStringha l'attributo[BindProperty].[BindProperty]associa i valori modulo e le stringhe di query al nome della proprietà.[BindProperty(SupportsGet = true)]è obbligatorio per l'associazione nelle richieste HTTP GET. -
Genres: contiene l'elenco dei generi.Genresconsente all'utente di selezionare un genere dall'elenco.SelectListrichiedeusing Microsoft.AspNetCore.Mvc.Rendering; -
MovieGenre: contiene il genere specifico selezionato dall'utente. Ad esempio, "Western". -
GenreseMovieGenresono utilizzati più avanti in questa esercitazione.
Avviso
Per motivi di sicurezza, è necessario acconsentire esplicitamente all'associazione dei dati della richiesta GET alle proprietà del modello di pagina. Verificare l'input dell'utente prima di eseguirne il mapping alle proprietà. Acconsentire esplicitamente all'associazione GET è utile in scenari basati su valori route o stringa di query.
Per associare una proprietà nelle richieste GET, impostare la proprietà [BindProperty] dell'attributo SupportsGet su true:
[BindProperty(SupportsGet = true)]
Per altre informazioni, vedere ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Aggiornare il metodo OnGetAsync della pagina di indice con il codice seguente:
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();
}
La prima riga del metodo OnGetAsync crea una query LINQ per selezionare i film:
// using System.Linq;
var movies = from m in _context.Movie
select m;
La query viene solo definita in questo punto, ma non viene eseguita nel database.
Se la proprietà SearchString non è null o vuota, la query dei film viene modificata per filtrare gli elementi in base alla stringa di ricerca:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
Il codice s => s.Title.Contains() è un'espressione lambda. Le espressioni lambda vengono usate nelle query LINQ basate su metodo come argomenti per metodi dell'operatore di query standard, ad esempio il metodo Where o Contains. Le query LINQ non vengono eseguite quando vengono definite o quando vengono modificate chiamando un metodo, ad esempio Where, Containso OrderBy. L'esecuzione della query viene invece posticipata. La valutazione di un'espressione viene ritardata fino a quando non viene eseguito l'iterazione del relativo valore realizzato o viene chiamato il ToListAsync metodo . Per altre informazioni, vedere Esecuzione di query.
Nota
Il Contains metodo viene eseguito nel database, non nel codice C#. La distinzione tra maiuscole/minuscole nella query dipende dal database e dalle regole di confronto. In SQL Server Contains esegue il mapping a SQL LIKE che fa distinzione tra maiuscole e minuscole. SQLite con le regole di confronto predefinite è una combinazione di distinzione tra maiuscole e minuscole e di distinzione tra maiuscole e minuscole, a seconda della query. Per informazioni sull'esecuzione di query SQLite senza distinzione tra maiuscole e minuscole, vedere quanto segue:
- Questo problema di GitHub.
- Questo problema di GitHub
- Regole di confronto e distinzione tra maiuscole e minuscole
Passare alla pagina Film e aggiungere una stringa di query, ?searchString=Ghost ad esempio all'URL. Ad esempio: https://localhost:5001/Movies?searchString=Ghost. Vengono visualizzati i film filtrati.
Se il modello di route seguente viene aggiunto alla pagina Indice, la stringa di ricerca può essere passata come segmento di URL. Ad esempio: https://localhost:5001/Movies/Ghost.
@page "{searchString?}"
Il vincolo di route precedente consente la ricerca del titolo come dati della route (un segmento URL), anziché come valore della stringa di query. Il carattere ? in "{searchString?}" indica che questo parametro di route è facoltativo.
Il runtime di ASP.NET Core usa l'associazione di modelli per impostare il valore della proprietà SearchString dalla stringa di query (?searchString=Ghost) o dai dati della route (https://localhost:5001/Movies/Ghost). L'associazione di modelli non fa distinzione tra maiuscole e minuscole.
Tuttavia, non è previsto che gli utenti modifichino l'URL per cercare un filmato. In questo passaggio viene aggiunta l'interfaccia utente per filtrare i film. Rimuovere il vincolo di route "{searchString?}", se è stato aggiunto.
Aprire il Pages/Movies/Index.cshtml file e aggiungere il markup evidenziato nel codice seguente:
@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.*@
Il tag HTML <form> usa gli helper tag seguenti:
- Helper tag Form. Quando il modulo viene inviato, la stringa di filtro verrà inviata alla pagina Pages/Movies/Index tramite una stringa di query.
- Helper per tag di input
Salvare le modifiche e testare il filtro.
Ricerca in base al genere
Aggiornare il metodo OnGetAsync della pagina di indice con il codice seguente:
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();
}
Il codice seguente è una query LINQ che recupera tutti i generi dal database.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
L'elenco SelectList di generi viene creato selezionando generi distinti.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Aggiungere la ricerca per genere alla Razor pagina
Aggiornare l'elemento
Index.cshtml<form>come evidenziato nel markup seguente:@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.*@Eseguire il test dell'app effettuando una ricerca per genere, titolo del film e usando entrambi i filtri.