Parte 6. Adición de búsqueda a Razor Pages de ASP.NET Core
Nota:
Esta no es la versión más reciente de este artículo. Para la versión actual, consulte la versión de .NET 9 de este artículo.
Advertencia
Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulta la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulta la versión .NET 8 de este artículo.
Importante
Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.
Para la versión actual, consulte la versión de .NET 9 de este artículo.
Por Rick Anderson
En las secciones siguientes, se ha agregado la función de buscar películas por género o nombre.
Agregue el código resaltado siguiente 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; }
En el código anterior:
SearchString
: contiene el texto que los usuarios escriben en el cuadro de texto de búsqueda.SearchString
tiene el atributo[BindProperty]
.[BindProperty]
enlaza los valores del formulario y las cadenas de consulta con el mismo nombre que la propiedad.[BindProperty(SupportsGet = true)]
bse necesita para el enlace de las solicitudes GET de HTTP.Genres
: contiene la lista de géneros.Genres
permite al usuario seleccionar un género de la lista.SelectList
requiereusing Microsoft.AspNetCore.Mvc.Rendering;
.MovieGenre
: Contiene el género específico que el usuario selecciona. Por ejemplo, "Western".Genres
yMovieGenre
se utilizan posteriormente en este tutorial.
Advertencia
Por motivos de seguridad, debe participar en el enlace de datos de solicitud GET
con las propiedades del modelo de página. Compruebe las entradas de los usuarios antes de asignarlas a las propiedades. Si participa en el enlace de GET
, le puede ser útil al trabajar con escenarios que dependan de cadenas de consultas o valores de rutas.
Para enlazar una propiedad en solicitudes GET
, establezca la propiedad SupportsGet
del atributo [BindProperty]
en true
:
[BindProperty(SupportsGet = true)]
Para obtener más información, vea ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Actualice el método Movies/Index
de la página OnGetAsync
con el código siguiente:
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 primera línea del método OnGetAsync
crea una consulta LINQ para seleccionar las películas:
var movies = from m in _context.Movie
select m;
En este momento, solo se define la consulta y no se ejecuta en la base de datos.
Si la propiedad SearchString
no es null
ni está vacía, la consulta de películas se modifica para filtrar según la cadena de búsqueda:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
El código s => s.Title.Contains()
es una expresión lambda. Las lambdas se usan en consultas LINQ basadas en métodos como argumentos para métodos de operador de consulta estándar, tales como el método Where o Contains
. Las consultas LINQ no se ejecutan cuando se definen ni cuando se modifican mediante una llamada a un método como Where
, Contains
o OrderBy
. En su lugar, se aplaza la ejecución de la consulta. La evaluación de una expresión se aplaza hasta que su valor realizado se repite o se llama al método ToListAsync
. Para más información, vea Query Execution (Ejecución de consultas).
Nota
El método Contains se ejecuta en la base de datos, no en el código de C#. La distinción entre mayúsculas y minúsculas en la consulta depende de la base de datos y la intercalación. En SQL Server, Contains
se asigna a SQL LIKE, que distingue entre mayúsculas y minúsculas. SQLite con la intercalación predeterminada es una combinación que distingue mayúsculas y minúsculas y que no distingue mayúsculas y minúsculas, en función de la consulta. Para obtener información sobre cómo hacer que las consultas SQLite no distingan mayúsculas y minúsculas, vea lo siguiente:
Vaya a la página de películas y anexe una cadena de consulta como ?searchString=Ghost
a la dirección URL. Por ejemplo, https://localhost:5001/Movies?searchString=Ghost
. Se muestran las películas filtradas.
Si se agrega la siguiente plantilla de ruta a la página Index, la cadena de búsqueda se puede pasar como un segmento de dirección URL. Por ejemplo, https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
La restricción de ruta anterior permite buscar el título como datos de ruta (un segmento de dirección URL) en lugar de como un valor de cadena de consulta. El elemento ?
de "{searchString?}"
significa que se trata de un parámetro de ruta opcional.
El entorno de ejecución de ASP.NET Core usa el enlace de modelos para establecer el valor de la propiedad SearchString
de la cadena de consulta (?searchString=Ghost
) o de los datos de ruta (https://localhost:5001/Movies/Ghost
). El enlace de modelos no distingue entre mayúsculas y minúsculas.
Sin embargo, no se puede esperar que los usuarios modifiquen la dirección URL para buscar una película. En este paso, se agrega la interfaz de usuario para filtrar las películas. Si ha agregado la restricción de ruta "{searchString?}"
, quítela.
Abra el archivo Pages/Movies/Index.cshtml
y agregue el marcado resaltado en el siguiente código:
@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>
La etiqueta HTML <form>
usa los siguientes Asistentes de etiquetas:
- Asistente de etiquetas de formulario. Cuando se envía el formulario, la cadena de filtro se envía a la página Pages/Movies/Index a través de la cadena de consulta.
- Asistente de etiquetas de entrada
Guarde los cambios y pruebe el filtro.
Búsqueda por género
Actualice el método Movies/Index.cshtml.cs
de la página OnGetAsync
con el código siguiente:
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();
}
El código siguiente es una consulta LINQ que recupera todos los géneros de la base de datos.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
La SelectList
de géneros se crea mediante la proyección de los distintos géneros:
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Incorporación de búsqueda por género a una página de Razor
Actualice el Index.cshtml
elemento <form>
de como se destaca en el marcado siguiente:
@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>
Pruebe la aplicación buscando por género, por título de la película y por ambos:
Pasos siguientes
En las secciones siguientes, se ha agregado la función de buscar películas por género o nombre.
Agregue el código resaltado siguiente 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; }
En el código anterior:
SearchString
: contiene el texto que los usuarios escriben en el cuadro de texto de búsqueda.SearchString
tiene el atributo[BindProperty]
.[BindProperty]
enlaza los valores del formulario y las cadenas de consulta con el mismo nombre que la propiedad.[BindProperty(SupportsGet = true)]
bse necesita para el enlace de las solicitudes GET de HTTP.Genres
: contiene la lista de géneros.Genres
permite al usuario seleccionar un género de la lista.SelectList
requiereusing Microsoft.AspNetCore.Mvc.Rendering;
.MovieGenre
: Contiene el género específico que el usuario selecciona. Por ejemplo, "Western".Genres
yMovieGenre
se utilizan posteriormente en este tutorial.
Advertencia
Por motivos de seguridad, debe participar en el enlace de datos de solicitud GET
con las propiedades del modelo de página. Compruebe las entradas de los usuarios antes de asignarlas a las propiedades. Si participa en el enlace de GET
, le puede ser útil al trabajar con escenarios que dependan de cadenas de consultas o valores de rutas.
Para enlazar una propiedad en solicitudes GET
, establezca la propiedad SupportsGet
del atributo [BindProperty]
en true
:
[BindProperty(SupportsGet = true)]
Para obtener más información, vea ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Actualice el método OnGetAsync
de la página de índice con el código siguiente:
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 primera línea del método OnGetAsync
crea una consulta LINQ para seleccionar las películas:
// using System.Linq;
var movies = from m in _context.Movie
select m;
En este momento, solo se define la consulta y no se ejecuta en la base de datos.
Si la propiedad SearchString
no es null
ni está vacía, la consulta de películas se modifica para filtrar según la cadena de búsqueda:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
El código s => s.Title.Contains()
es una expresión lambda. Las lambdas se usan en consultas LINQ basadas en métodos como argumentos para métodos de operador de consulta estándar, tales como el método Where o Contains
. Las consultas LINQ no se ejecutan cuando se definen ni cuando se modifican mediante una llamada a un método como Where
, Contains
o OrderBy
. En su lugar, se aplaza la ejecución de la consulta. La evaluación de una expresión se aplaza hasta que su valor realizado se repite o se llama al método ToListAsync
. Para más información, vea Query Execution (Ejecución de consultas).
Nota
El método Contains se ejecuta en la base de datos, no en el código de C#. La distinción entre mayúsculas y minúsculas en la consulta depende de la base de datos y la intercalación. En SQL Server, Contains
se asigna a SQL LIKE, que distingue entre mayúsculas y minúsculas. SQLite con la intercalación predeterminada es una combinación que distingue mayúsculas y minúsculas y que no distingue mayúsculas y minúsculas, en función de la consulta. Para obtener información sobre cómo hacer que las consultas SQLite no distingan mayúsculas y minúsculas, vea lo siguiente:
Vaya a la página de películas y anexe una cadena de consulta como ?searchString=Ghost
a la dirección URL. Por ejemplo, https://localhost:5001/Movies?searchString=Ghost
. Se muestran las películas filtradas.
Si se agrega la siguiente plantilla de ruta a la página Index, la cadena de búsqueda se puede pasar como un segmento de dirección URL. Por ejemplo, https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
La restricción de ruta anterior permite buscar el título como datos de ruta (un segmento de dirección URL) en lugar de como un valor de cadena de consulta. El elemento ?
de "{searchString?}"
significa que se trata de un parámetro de ruta opcional.
El entorno de ejecución de ASP.NET Core usa el enlace de modelos para establecer el valor de la propiedad SearchString
de la cadena de consulta (?searchString=Ghost
) o de los datos de ruta (https://localhost:5001/Movies/Ghost
). El enlace de modelos no distingue entre mayúsculas y minúsculas.
Sin embargo, no se puede esperar que los usuarios modifiquen la dirección URL para buscar una película. En este paso, se agrega la interfaz de usuario para filtrar las películas. Si ha agregado la restricción de ruta "{searchString?}"
, quítela.
Abra el archivo Pages/Movies/Index.cshtml
y agregue el marcado resaltado en el siguiente código:
@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.*@
La etiqueta HTML <form>
usa los siguientes Asistentes de etiquetas:
- Asistente de etiquetas de formulario. Cuando se envía el formulario, la cadena de filtro se envía a la página Pages/Movies/Index a través de la cadena de consulta.
- Asistente de etiquetas de entrada
Guarde los cambios y pruebe el filtro.
Búsqueda por género
Actualice el método Movies/Index.cshtml.cs
de la página OnGetAsync
con el código siguiente:
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();
}
El código siguiente es una consulta LINQ que recupera todos los géneros de la base de datos.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
La SelectList
de géneros se crea mediante la proyección de los distintos géneros.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Incorporación de búsqueda por género a una página de Razor
Actualice el Index.cshtml
elemento <form>
de como se destaca en el marcado siguiente:
@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>
Pruebe la aplicación al buscar por género, título de la película y ambos.
Pasos siguientes
En las secciones siguientes, se ha agregado la función de buscar películas por género o nombre.
Agregue el código resaltado siguiente 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; }
En el código anterior:
SearchString
: contiene el texto que los usuarios escriben en el cuadro de texto de búsqueda.SearchString
tiene el atributo[BindProperty]
.[BindProperty]
enlaza los valores del formulario y las cadenas de consulta con el mismo nombre que la propiedad.[BindProperty(SupportsGet = true)]
bse necesita para el enlace de las solicitudes GET de HTTP.Genres
: contiene la lista de géneros.Genres
permite al usuario seleccionar un género de la lista.SelectList
requiereusing Microsoft.AspNetCore.Mvc.Rendering;
.MovieGenre
: Contiene el género específico que el usuario selecciona. Por ejemplo, "Western".Genres
yMovieGenre
se utilizan posteriormente en este tutorial.
Advertencia
Por motivos de seguridad, debe participar en el enlace de datos de solicitud GET
con las propiedades del modelo de página. Compruebe las entradas de los usuarios antes de asignarlas a las propiedades. Si participa en el enlace de GET
, le puede ser útil al trabajar con escenarios que dependan de cadenas de consultas o valores de rutas.
Para enlazar una propiedad en solicitudes GET
, establezca la propiedad SupportsGet
del atributo [BindProperty]
en true
:
[BindProperty(SupportsGet = true)]
Para obtener más información, vea ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Actualice el método OnGetAsync
de la página de índice con el código siguiente:
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 primera línea del método OnGetAsync
crea una consulta LINQ para seleccionar las películas:
// using System.Linq;
var movies = from m in _context.Movie
select m;
En este momento, solo se define la consulta y no se ejecuta en la base de datos.
Si la propiedad SearchString
no es null
ni está vacía, la consulta de películas se modifica para filtrar según la cadena de búsqueda:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
El código s => s.Title.Contains()
es una expresión lambda. Las lambdas se usan en consultas LINQ basadas en métodos como argumentos para métodos de operador de consulta estándar, tales como el método Where o Contains
. Las consultas LINQ no se ejecutan cuando se definen ni cuando se modifican mediante una llamada a un método como Where
, Contains
o OrderBy
. En su lugar, se aplaza la ejecución de la consulta. La evaluación de una expresión se aplaza hasta que su valor realizado se repite o se llama al método ToListAsync
. Para más información, vea Query Execution (Ejecución de consultas).
Nota
El método Contains se ejecuta en la base de datos, no en el código de C#. La distinción entre mayúsculas y minúsculas en la consulta depende de la base de datos y la intercalación. En SQL Server, Contains
se asigna a SQL LIKE, que distingue entre mayúsculas y minúsculas. SQLite con la intercalación predeterminada es una combinación que distingue mayúsculas y minúsculas y que no distingue mayúsculas y minúsculas, en función de la consulta. Para obtener información sobre cómo hacer que las consultas SQLite no distingan mayúsculas y minúsculas, vea lo siguiente:
- Este problema de GitHub
- Este problema de GitHub
- Intercalaciones y distinción de mayúsculas y minúsculas
Vaya a la página de películas y anexe una cadena de consulta como ?searchString=Ghost
a la dirección URL. Por ejemplo, https://localhost:5001/Movies?searchString=Ghost
. Se muestran las películas filtradas.
Si se agrega la siguiente plantilla de ruta a la página Index, la cadena de búsqueda se puede pasar como un segmento de dirección URL. Por ejemplo, https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
La restricción de ruta anterior permite buscar el título como datos de ruta (un segmento de dirección URL) en lugar de como un valor de cadena de consulta. El elemento ?
de "{searchString?}"
significa que se trata de un parámetro de ruta opcional.
El entorno de ejecución de ASP.NET Core usa el enlace de modelos para establecer el valor de la propiedad SearchString
de la cadena de consulta (?searchString=Ghost
) o de los datos de ruta (https://localhost:5001/Movies/Ghost
). El enlace de modelos no distingue entre mayúsculas y minúsculas.
Sin embargo, no se puede esperar que los usuarios modifiquen la dirección URL para buscar una película. En este paso, se agrega la interfaz de usuario para filtrar las películas. Si ha agregado la restricción de ruta "{searchString?}"
, quítela.
Abra el archivo Pages/Movies/Index.cshtml
y agregue el marcado resaltado en el siguiente código:
@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.*@
La etiqueta HTML <form>
usa los siguientes Asistentes de etiquetas:
- Asistente de etiquetas de formulario. Cuando se envía el formulario, la cadena de filtro se envía a la página Pages/Movies/Index a través de la cadena de consulta.
- Asistente de etiquetas de entrada
Guarde los cambios y pruebe el filtro.
Búsqueda por género
Actualice el método OnGetAsync
de la página de índice con el código siguiente:
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();
}
El código siguiente es una consulta LINQ que recupera todos los géneros de la base de datos.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
La SelectList
de géneros se crea mediante la proyección de los distintos géneros.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Incorporación de búsqueda por género a una página de Razor
Actualice el Index.cshtml
elemento <form>
de como se destaca en el marcado siguiente:
@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>
Pruebe la aplicación al buscar por género, título de la película y ambos.
Pasos siguientes
En las secciones siguientes, se ha agregado la función de buscar películas por género o nombre.
Agregue el código resaltado siguiente 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; }
En el código anterior:
SearchString
: contiene el texto que los usuarios escriben en el cuadro de texto de búsqueda.SearchString
tiene el atributo[BindProperty]
.[BindProperty]
enlaza los valores del formulario y las cadenas de consulta con el mismo nombre que la propiedad.[BindProperty(SupportsGet = true)]
bse necesita para el enlace de las solicitudes GET de HTTP.Genres
: contiene la lista de géneros.Genres
permite al usuario seleccionar un género de la lista.SelectList
requiereusing Microsoft.AspNetCore.Mvc.Rendering;
.MovieGenre
: Contiene el género específico que el usuario selecciona. Por ejemplo, "Western".Genres
yMovieGenre
se utilizan posteriormente en este tutorial.
Advertencia
Por motivos de seguridad, debe participar en el enlace de datos de solicitud GET
con las propiedades del modelo de página. Compruebe las entradas de los usuarios antes de asignarlas a las propiedades. Si participa en el enlace de GET
, le puede ser útil al trabajar con escenarios que dependan de cadenas de consultas o valores de rutas.
Para enlazar una propiedad en solicitudes GET
, establezca la propiedad SupportsGet
del atributo [BindProperty]
en true
:
[BindProperty(SupportsGet = true)]
Para obtener más información, vea ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Actualice el método OnGetAsync
de la página de índice con el código siguiente:
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 primera línea del método OnGetAsync
crea una consulta LINQ para seleccionar las películas:
// using System.Linq;
var movies = from m in _context.Movie
select m;
En este momento, solo se define la consulta y no se ejecuta en la base de datos.
Si la propiedad SearchString
no es NULL ni está vacía, la consulta de películas se modifica para filtrar según la cadena de búsqueda:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
El código s => s.Title.Contains()
es una expresión lambda. Las lambdas se usan en consultas LINQ basadas en métodos como argumentos para métodos de operador de consulta estándar, tales como el método Where o Contains
. Las consultas LINQ no se ejecutan cuando se definen ni cuando se modifican mediante una llamada a un método como Where
, Contains
o OrderBy
. En su lugar, se aplaza la ejecución de la consulta. La evaluación de una expresión se aplaza hasta que su valor realizado se repite o se llama al método ToListAsync
. Para más información, vea Query Execution (Ejecución de consultas).
Nota
El método Contains se ejecuta en la base de datos, no en el código de C#. La distinción entre mayúsculas y minúsculas en la consulta depende de la base de datos y la intercalación. En SQL Server, Contains
se asigna a SQL LIKE, que distingue entre mayúsculas y minúsculas. SQLite con la intercalación predeterminada es una combinación que distingue mayúsculas y minúsculas y que no distingue mayúsculas y minúsculas, en función de la consulta. Para obtener información sobre cómo hacer que las consultas SQLite no distingan mayúsculas y minúsculas, vea lo siguiente:
- Este problema de GitHub
- Este problema de GitHub
- Intercalaciones y distinción de mayúsculas y minúsculas
Vaya a la página de películas y anexe una cadena de consulta como ?searchString=Ghost
a la dirección URL. Por ejemplo, https://localhost:5001/Movies?searchString=Ghost
. Se muestran las películas filtradas.
Si se agrega la siguiente plantilla de ruta a la página Index, la cadena de búsqueda se puede pasar como un segmento de dirección URL. Por ejemplo, https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
La restricción de ruta anterior permite buscar el título como datos de ruta (un segmento de dirección URL) en lugar de como un valor de cadena de consulta. El elemento ?
de "{searchString?}"
significa que se trata de un parámetro de ruta opcional.
El entorno de ejecución de ASP.NET Core usa el enlace de modelos para establecer el valor de la propiedad SearchString
de la cadena de consulta (?searchString=Ghost
) o de los datos de ruta (https://localhost:5001/Movies/Ghost
). El enlace de modelos no distingue entre mayúsculas y minúsculas.
Sin embargo, no se puede esperar que los usuarios modifiquen la dirección URL para buscar una película. En este paso, se agrega la interfaz de usuario para filtrar las películas. Si ha agregado la restricción de ruta "{searchString?}"
, quítela.
Abra el archivo Pages/Movies/Index.cshtml
y agregue el marcado resaltado en el siguiente código:
@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.*@
La etiqueta HTML <form>
usa los siguientes Asistentes de etiquetas:
- Asistente de etiquetas de formulario. Cuando se envía el formulario, la cadena de filtro se envía a la página Pages/Movies/Index a través de la cadena de consulta.
- Asistente de etiquetas de entrada
Guarde los cambios y pruebe el filtro.
Búsqueda por género
Actualice el método OnGetAsync
de la página de índice con el código siguiente:
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();
}
El código siguiente es una consulta LINQ que recupera todos los géneros de la base de datos.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
La SelectList
de géneros se crea mediante la proyección de los distintos géneros.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Incorporación de búsqueda por género a una página de Razor
Actualice el Index.cshtml
elemento <form>
de como se destaca en el marcado siguiente:
@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>
Pruebe la aplicación al buscar por género, título de la película y ambos.
Pasos siguientes
En las secciones siguientes, se ha agregado la función de buscar películas por género o nombre.
Agregue la siguiente instrucción using resaltada y las propiedades 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; }
En el código anterior:
SearchString
: contiene el texto que los usuarios escriben en el cuadro de texto de búsqueda.SearchString
tiene el atributo[BindProperty]
.[BindProperty]
enlaza los valores del formulario y las cadenas de consulta con el mismo nombre que la propiedad.[BindProperty(SupportsGet = true)]
bse necesita para el enlace de las solicitudes GET de HTTP.Genres
: contiene la lista de géneros.Genres
permite al usuario seleccionar un género de la lista.SelectList
requiereusing Microsoft.AspNetCore.Mvc.Rendering;
.MovieGenre
: Contiene el género específico que el usuario selecciona. Por ejemplo, "Western".Genres
yMovieGenre
se utilizan posteriormente en este tutorial.
Advertencia
Por motivos de seguridad, debe participar en el enlace de datos de solicitud GET
con las propiedades del modelo de página. Compruebe las entradas de los usuarios antes de asignarlas a las propiedades. Si participa en el enlace de GET
, le puede ser útil al trabajar con escenarios que dependan de cadenas de consultas o valores de rutas.
Para enlazar una propiedad en solicitudes GET
, establezca la propiedad SupportsGet
del atributo [BindProperty]
en true
:
[BindProperty(SupportsGet = true)]
Para obtener más información, vea ASP.NET Core Community Standup: Bind on GET discussion (YouTube).
Actualice el método OnGetAsync
de la página de índice con el código siguiente:
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 primera línea del método OnGetAsync
crea una consulta LINQ para seleccionar las películas:
// using System.Linq;
var movies = from m in _context.Movie
select m;
En este momento, solo se define la consulta y no se ejecuta en la base de datos.
Si la propiedad SearchString
no es NULL ni está vacía, la consulta de películas se modifica para filtrar según la cadena de búsqueda:
if (!string.IsNullOrEmpty(SearchString))
{
movies = movies.Where(s => s.Title.Contains(SearchString));
}
El código s => s.Title.Contains()
es una expresión lambda. Las lambdas se usan en consultas LINQ basadas en métodos como argumentos para métodos de operador de consulta estándar, tales como el método Where o Contains
. Las consultas LINQ no se ejecutan cuando se definen ni cuando se modifican mediante una llamada a un método como Where
, Contains
o OrderBy
. En su lugar, se aplaza la ejecución de la consulta. La evaluación de una expresión se aplaza hasta que su valor realizado se repite o se llama al método ToListAsync
. Para más información, vea Query Execution (Ejecución de consultas).
Nota
El método Contains se ejecuta en la base de datos, no en el código de C#. La distinción entre mayúsculas y minúsculas en la consulta depende de la base de datos y la intercalación. En SQL Server, Contains
se asigna a SQL LIKE, que distingue entre mayúsculas y minúsculas. SQLite con la intercalación predeterminada es una combinación que distingue mayúsculas y minúsculas y que no distingue mayúsculas y minúsculas, en función de la consulta. Para obtener información sobre cómo hacer que las consultas SQLite no distingan mayúsculas y minúsculas, vea lo siguiente:
- Este problema de GitHub
- Este problema de GitHub
- Intercalaciones y distinción de mayúsculas y minúsculas
Vaya a la página de películas y anexe una cadena de consulta como ?searchString=Ghost
a la dirección URL. Por ejemplo, https://localhost:5001/Movies?searchString=Ghost
. Se muestran las películas filtradas.
Si se agrega la siguiente plantilla de ruta a la página Index, la cadena de búsqueda se puede pasar como un segmento de dirección URL. Por ejemplo, https://localhost:5001/Movies/Ghost
.
@page "{searchString?}"
La restricción de ruta anterior permite buscar el título como datos de ruta (un segmento de dirección URL) en lugar de como un valor de cadena de consulta. El elemento ?
de "{searchString?}"
significa que se trata de un parámetro de ruta opcional.
El entorno de ejecución de ASP.NET Core usa el enlace de modelos para establecer el valor de la propiedad SearchString
de la cadena de consulta (?searchString=Ghost
) o de los datos de ruta (https://localhost:5001/Movies/Ghost
). El enlace de modelos no distingue entre mayúsculas y minúsculas.
Sin embargo, no se puede esperar que los usuarios modifiquen la dirección URL para buscar una película. En este paso, se agrega la interfaz de usuario para filtrar las películas. Si ha agregado la restricción de ruta "{searchString?}"
, quítela.
Abra el archivo Pages/Movies/Index.cshtml
y agregue el marcado resaltado en el siguiente código:
@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.*@
La etiqueta HTML <form>
usa los siguientes Asistentes de etiquetas:
- Asistente de etiquetas de formulario. Cuando se envía el formulario, la cadena de filtro se envía a la página Pages/Movies/Index a través de la cadena de consulta.
- Asistente de etiquetas de entrada
Guarde los cambios y pruebe el filtro.
Búsqueda por género
Actualice el método OnGetAsync
de la página de índice con el código siguiente:
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();
}
El código siguiente es una consulta LINQ que recupera todos los géneros de la base de datos.
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
La SelectList
de géneros se crea mediante la proyección de los distintos géneros.
Genres = new SelectList(await genreQuery.Distinct().ToListAsync());
Incorporación de búsqueda por género a una página de Razor
Actualice el
Index.cshtml
elemento<form>
de como se destaca en el marcado siguiente:@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.*@
Pruebe la aplicación al buscar por género, título de la película y ambos.