Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le 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 si aggiunge la possibilità di cercare film in base al genere o 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 definita solo a questo punto. Non viene eseguito contro il database.
Se la proprietà SearchString non è null né vuota, la query dei filmati viene modificata per filtrare 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:
Passare alla pagina Film e aggiungere una stringa di query, ?searchString=Ghost ad esempio all'URL. Ad esempio: https://localhost:7247/Movies?searchString=Ghost. Vengono visualizzati i film filtrati.
Se si aggiunge il modello di route seguente alla pagina Indice, è possibile passare la stringa di ricerca come segmento di URL. Ad esempio: https://localhost:7247/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:7247/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 film. In questo passaggio si aggiunge 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 si invia il modulo, la stringa di filtro viene inviata alla pagina Pages/Movies/Index tramite la 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 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.