Ejercicio: Adición de una página de lista de pizzas con un formulario
En esta unidad, creará un formulario en el proyecto RazorPagesPizza con Razor Pages para separar la lógica de la página de su presentación.
Creación de una página
El directorio del proyecto RazorPagesPizza está abierto actualmente en Visual Studio Code. Ejecute el comando siguiente de la CLI de .NET Core en el shell de comandos:
dotnet new page --name Pizza --namespace RazorPagesPizza.Pages --output Pages
El comando anterior:
- Crea los archivos siguientes en el espacio de nombres
RazorPagesPizza.Pages:- Pizza.cshtml—La página de Razor
- Pizza.cshtml.cs—La clase
PageModelque la acompaña
- Almacena ambos archivos en el directorio Pages del proyecto.
Tenga en cuenta que no hay nada mágico en el uso de la CLI para crear estos archivos. También puede crear los archivos manualmente; el comando de la CLI es simplemente un acceso directo para hacerlo.
Examen de la estructura de la página de Razor
Abra la nueva página de Razor Pages/Pizza.cshtml. Examine el marcado del archivo:
@page @model RazorPagesPizza.Pages.PizzaModel @{ }La página de Razor anterior contiene palabras clave reservadas de Razor:
- La directiva
@pagees la que convierte a la página en una página de Razor. Indica que la página puede controlar solicitudes HTTP. La directiva@pagedebe ser la primera en una página de Razor. - La directiva
@modelespecifica el tipo de modelo puesto a disposición de la página de Razor. En este caso, el tipo es el nombre de la clase derivada dePageModel, con el prefijo de su espacio de nombres. Como recordará, esa clase se define en Pages/Pizza.cshtml.cs.
- La directiva
Representación de HTML y transición a C#
El marcado siguiente es un ejemplo de un símbolo @ seguido de código de C#. El código establece el valor de clave Title de la colección ViewData en Create. La sintaxis Razor usa el símbolo @ para realizar la transición de HTML a C#. Si el símbolo @ va seguido de una palabra clave reservada de Razor, realiza la transición a marcado específico de Razor; en caso contrario, realiza la transición a C#. Razor evalúa las expresiones de C# y las representa en la salida HTML.
@{
ViewData["Title"] = "Pizza";
}
Una página de Razor admite la sintaxis Razor que permite combinar HTML y C#. El código de C# define la lógica de representación dinámica de la página en el servidor. El lenguaje de Razor predeterminado es HTML. La representación de HTML a partir del marcado de Razor no es diferente de la representación de HTML desde un archivo HTML. El servidor representa el marcado HTML en los archivos de la página de Razor .cshtml sin cambios. En Razor Pages, se puede usar HTML de la forma habitual. Al mismo tiempo, puede aprovechar las ventajas de las características de Razor (eficaces y que ahorran tiempo) mientras aprende a usarlas.
Adición de las clases Pizza y PizzaService
Antes de empezar a implementar el formulario para administrar pizzas, es necesario tener un almacén de datos en el que poder realizar operaciones.
Se necesita una clase model para representar una pizza del inventario. El modelo contiene propiedades que representan las características de una pizza. El modelo se usa para pasar datos en la aplicación web y para conservar opciones de pizza en el almacén de datos. En esta unidad, ese almacén de datos va a ser un servicio de almacenamiento en caché en memoria local simple. En una aplicación real se recomienda usar una base de datos, como SQL Server, con Entity Framework Core.
Creación de un modelo de pizza
Ejecute el comando siguiente para crear una carpeta
Models:mkdir ModelsSeleccione la carpeta
Modelsen Visual Studio Code y agregue un nuevo archivo de nombrePizza.cs.La raíz del proyecto ahora contiene un directorio Models con un archivo Pizza.cs vacío. El nombre del directorio Models es una convención.
Agregue el siguiente código a Models/Pizza.cs para definir una pizza. Guarde los cambios.
namespace RazorPagesPizza.Models { public class Pizza { public int Id { get; set; } [Required] public string Name { get; set; } public PizzaSize Size { get; set; } public bool IsGlutenFree { get; set; } [Range(0.01, 9999.99)] public decimal Price { get; set; } } public enum PizzaSize { Small, Medium, Large } }Sugerencia
Los métodos abreviados de teclado siguientes son útiles en el editor de Cloud Shell.
Método abreviado de teclado Comando CTRL+V (Windows)
⌘+V (macOS)Pegar CTRL+S (Windows)
⌘+S (macOS)Guardar
Incorporación de un servicio de datos
Ejecute el comando siguiente para crear una carpeta
Services:mkdir ServicesSeleccione la carpeta en Visual Studio Code y agregue un nuevo archivo de nombre
PizzaService.cs.Agregue el siguiente código a Services/PizzaService.cs para crear un servicio de datos de pizzas en memoria. Guarde los cambios.
using RazorPagesPizza.Models; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace RazorPagesPizza.Services { public static class PizzaService { static List<Pizza> Pizzas { get; } static int nextId = 3; static PizzaService() { Pizzas = new List<Pizza> { new Pizza { Id = 1, Name = "Classic Italian", Price=20.00M, Size=PizzaSize.Large, IsGlutenFree = false }, new Pizza { Id = 2, Name = "Veggie", Price=15.00M, Size=PizzaSize.Small, IsGlutenFree = true } }; } public static List<Pizza> GetAll() => Pizzas; public static Pizza Get(int id) => Pizzas.FirstOrDefault(p => p.Id == id); public static void Add(Pizza pizza) { pizza.Id = nextId++; Pizzas.Add(pizza); } public static void Delete(int id) { var pizza = Get(id); if (pizza is null) return; Pizzas.Remove(pizza); } public static void Update(Pizza pizza) { var index = Pizzas.FindIndex(p => p.Id == pizza.Id); if (index == -1) return; Pizzas[index] = pizza; } } }Este es un sencillo servicio de almacenamiento en caché de datos en memoria con dos pizzas de manera predeterminada que la aplicación web va a usar con fines de demostración. Cuando se detiene y se inicia la aplicación web, la caché de datos en memoria se restablece a las dos pizzas predeterminadas del creador de
PizzaService.
Adición de marcado de formulación en la página de Razor Pizza
Reemplace el contenido de Pages/Pizza.cshtml por el marcado siguiente. Guarde los cambios.
@page
@using RazorPagesPizza.Models
@model RazorPagesPizza.Pages.PizzaModel
@{
ViewData["Title"] = "Pizza List";
}
<h1>Pizza List 🍕</h1>
<form method="post" class="card p-3">
<div class="row">
<div asp-validation-summary="All"></div>
</div>
<div class="form-group mb-0 align-middle">
<label asp-for="NewPizza.Name">Name</label>
<input type="text" asp-for="NewPizza.Name" class="mr-5">
<label asp-for="NewPizza.Size">Size</label>
<select asp-for="NewPizza.Size" asp-items="Html.GetEnumSelectList<PizzaSize>()" class="mr-5"></select>
<label asp-for="NewPizza.Price"></label>
<input asp-for="NewPizza.Price" class="mr-5" />
<label asp-for="NewPizza.IsGlutenFree">Gluten Free</label>
<input type="checkbox" asp-for="NewPizza.IsGlutenFree" class="mr-5">
<button class="btn btn-primary">Add</button>
</div>
</form>
<table class="table mt-5">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Price</th>
<th scope="col">Size</th>
<th scope="col">Gluten Free</th>
<th scope="col">Delete</th>
</tr>
</thead>
@foreach (var pizza in Model.pizzas)
{
<tr>
<td>@pizza.Name</td>
<td>@($"{pizza.Price:C}")</td>
<td>@pizza.Size</td>
<td>@Model.GlutenFreeText(pizza)</td>
<td>
<form method="post" asp-page-handler="Delete" asp-route-id="@pizza.Id">
<button class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
}
</table>
@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
Sugerencia
Los métodos abreviados de teclado siguientes son útiles en el editor de Cloud Shell.
| Método abreviado de teclado | Comando |
|---|---|
| CTRL+V (Windows) ⌘+V (macOS) |
Pegar |
| CTRL+S (Windows) ⌘+S (macOS) |
Guardar |
En la página de Razor Pizza se usa HTML y Razor para admitir un formulario de creación de producto. El formulario acepta los valores Name y Price para el producto que se va a crear. Con relativamente poco marcado, se han proporcionado características dinámicas a través de aplicaciones auxiliares de etiquetas de Razor. La validación de entradas de formulario del lado cliente se habilita mediante la inclusión de la vista parcial Pages/Shared/_ValidationScriptsPartial.cshtml. El contenido de la vista parcial se inserta en la sección Scripts de la página de diseño.
Revisión de las aplicaciones auxiliares de etiquetas de Razor
Las aplicaciones auxiliares de etiquetas abordan las ineficacias del cambio de contexto entre HTML y C#. La mayoría de las aplicaciones auxiliares de etiquetas integradas de ASP.NET Core amplían los elementos HTML estándar. Las aplicaciones auxiliares de etiquetas proporcionan atributos adicionales del lado servidor para los elementos HTML, lo que aumenta su solidez.
En esta página hay cuatro aplicaciones auxiliares de etiquetas:
- Parcial
- Etiqueta
- Entrada
- Mensaje de resumen de la validación
Asistente de etiquetas parciales
El marcado siguiente usa la aplicación auxiliar de etiquetas parciales para representar una vista parcial de forma asincrónica:
<partial name="_ValidationScriptsPartial" />
El atributo name de la aplicación auxiliar de etiquetas parciales acepta el nombre de vista parcial sin la extensión de archivo. Un proceso de detección de vistas ubica la vista parcial en el proyecto.
La sintaxis de esta aplicación auxiliar de etiquetas es una alternativa a la sintaxis del asistente de HTML siguiente:
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
Asistente de etiquetas de elementos de etiqueta
En el marcado siguiente se usa la aplicación auxiliar de etiquetas:
<label asp-for="NewPizza.Name" class="control-label"></label>
La aplicación auxiliar de etiquetas extiende el elemento HTML <label> estándar. Como es común para muchas aplicaciones auxiliares de etiquetas, usa un atributo asp-for. El atributo acepta una propiedad PageModel especificada. En este caso, el valor de la propiedad Name de PageModel se representará como el contenido de un elemento <label> HTML. El ámbito del atributo asp-for es PageModel para la página de Razor, por lo que no se usa el símbolo @. La etiqueta es dinámica, como se necesita aquí, pero sigue siendo compacta y fácil de agregar en el marcado.
Asistente de etiquetas de entrada
En el marcado siguiente se usa la aplicación auxiliar de etiquetas de entrada. Extiende el elemento HTML <input> estándar. También usa un atributo asp-for para especificar una propiedad PageModel.
<input asp-for="NewPizza.Name" class="form-control" />
El asistente de etiquetas Input hace lo siguiente:
- Evalúa la propiedad
NewPizza.Name, como la aplicación auxiliar de etiquetas. - Agrega un atributo HTML
idynameen función de esa propiedad. - Establece el tipo de entrada correctamente. Por ejemplo, si el tipo de propiedad especificado es
bool, se usa un tipo de entrada decheckboxen el HTML generado. En este caso, el tipo de propiedadNewPizza.Nameesstring. La propiedadNewPizza.Namese establece mediante los atributos de anotación de datos del modelo que se revisarán más adelante en este módulo. - Proporciona la validación del lado cliente mediante JQuery, en función de los atributos de anotación de datos del modelo que se proporcionan a través de
PageModel. - Solicita al motor de Razor que proporcione una validación del lado servidor adicional y más sólida, si la validación del lado cliente se ha realizado de forma correcta. El ciclo de vida de los eventos HTTP POST de la página de Razor Pizza, que incluye la validación de entradas del lado cliente y del lado servidor, se describirá más adelante en este módulo.
La salida HTML siguiente se genera a partir de la aplicación auxiliar de etiquetas de entrada que se encuentra en la página Pizza:
<input name="NewPizza.Name" class="form-control" id="NewPizza_Name" type="text" value="" data-val-required="The Name field is required." data-val="true">
Asistente de etiquetas de resumen de validación
En el marcado siguiente se usa la aplicación auxiliar de etiquetas de resumen de validación. Muestra un mensaje de validación para una única propiedad del modelo.
<div asp-validation-summary="All"></div>
La aplicación auxiliar de etiquetas de entrada agrega atributos HTML5 data- a los elementos de entrada. Los atributos se basan en las propiedades de las clases de modelo de C#. Mientras se realiza la validación del lado cliente con capacidad de respuesta, la validación también se realiza en el servidor, lo que resulta más seguro.
La aplicación auxiliar de etiquetas de resumen de validación representa el HTML siguiente:
<input name="NewPizza.Price" class="form-control" id="NewPizza_Price" type="text" value="" data-val-required="The Price field is required." data-val="true" data-val-range-min="0.01" data-val-range-max="9999.99" data-val-range="The field Price must be between 0.01 and 9999.99." data-val-number="The field Price must be a number.">
type, data-val-range-min, data-val-range-max y la respuesta de error se establecen dinámicamente mediante las anotaciones de datos del modelo para la propiedad Product.Price del modelo.
Se creó la página de Razor de creación de producto. Para procesar las interacciones del formulario, es necesario modificar la clase PageModel para controlar la solicitud HTTP POST del formulario. A continuación, exploraremos las interacciones PageModel.
¿Necesita ayuda? Consulte nuestra guía de solución de problemas o notifique un problema para enviar comentarios específicos.