Ejercicio: Adición de la validación de datos del lado servidor y del lado cliente al formulario de dirección
Blazor puede enlazar formularios a modelos en la aplicación. Si decora esos modelos con anotaciones de datos, puede obtener validaciones del lado cliente y servidor sin escribir código adicional.
Como debe ser, la aplicación no hace pedidos cuando un cliente no escribe un nombre y algunos campos de dirección. El equipo quiere que mejore las validaciones para que se incluyan más campos. También les gustaría tener algunas longitudes mínimas y validación de caracteres.
En este ejercicio, reemplazará la validación actual del lado servidor para usar anotaciones de datos. Verá cómo administrar los mensajes de validación y mejorar la compatibilidad con la validación lista para usar. En el último paso, controlará cómo se envía el formulario, que solo se envía cuando todos los campos son válidos.
Adición de anotaciones de datos a un modelo de Blazor
En el explorador de archivos de Visual Studio Code, expanda Model y, después, seleccione Address.cs.
Al comienzo de la clase, agregue una referencia a
System.ComponentModel.DataAnnotations
.using System.ComponentModel.DataAnnotations;
Para cada campo necesario, agregue una anotación de datos.
public class Address { public int Id { get; set; } [Required, MinLength(3), MaxLength(100)] public string Name { get; set; } [Required, MinLength(5), MaxLength(100)] public string Line1 { get; set; } [MaxLength(100)] public string Line2 { get; set; } [Required, MinLength(3), MaxLength(50)] public string City { get; set; } [Required, MinLength(3), MaxLength(20)] public string Region { get; set; } [Required, RegularExpression(@"^([0-9]{5})$")] public string PostalCode { get; set; } }
En el explorador de archivos, expanda Pages y, a continuación, seleccione Checkout.razor.
Encima de la etiqueta
</EditForm>
de cierre, agregue el resumen de validación y el validador de anotaciones de datos.<ValidationSummary /> <DataAnnotationsValidator /> </EditForm> </div>
En la etiqueta de EditForm, reemplace el parámetro
OnSubmit
para usar el envío válido.<EditForm Model=Order.DeliveryAddress OnValidSubmit=PlaceOrder>
Ahora puede eliminar la lógica personalizada del lado servidor para probar si la dirección es válida. Elimine el método
CheckSubmission
en el bloque@code
.
Prueba de las nuevas validaciones de anotación de datos
En Visual Studio Code, presione F5 o seleccione Ejecutar>Iniciar depuración.
Intente pedir algunas pizzas sin especificar ninguna información y, después, con información incompleta. Observe los mensajes de error detallados de cada campo.
Esta interacción mejora las comprobaciones de errores de cada campo, pero el error de cada campo estaría mucho mejor junto al campo con el que se relaciona.
Presione Mayús + F5 para detener la ejecución de la aplicación.
Mejora de los mensajes de error de EditFrom
En el explorador de archivos, expanda Pages y, a continuación, seleccione Checkout.razor.
Elimine el componente
<ValidationSummary />
de Blazor.<DataAnnotationsValidator /> </EditForm> </div>
En el explorador de archivos, expanda Shared y, después, seleccione AddressEditor.razor.
Debajo de cada campo, agregue un mensaje de validación personalizado.
<div class="form-field"> <label>Name:</label> <div> <InputText @bind-Value="Address.Name" /> <ValidationMessage For="@(() => Address.Name)" /> </div> </div> <div class="form-field"> <label>Line 1:</label> <div> <InputText @bind-Value="Address.Line1" /> <ValidationMessage For="@(() => Address.Line1)" /> </div> </div> <div class="form-field"> <label>Line 2:</label> <div> <InputText @bind-Value="Address.Line2" /> <ValidationMessage For="@(() => Address.Line2)" /> </div> </div> <div class="form-field"> <label>City:</label> <div> <InputText @bind-Value="Address.City" /> <ValidationMessage For="@(() => Address.City)" /> </div> </div> <div class="form-field"> <label>Region:</label> <div> <InputText @bind-Value="Address.Region" /> <ValidationMessage For="@(() => Address.Region)" /> </div> </div> <div class="form-field"> <label>Postal code:</label> <div> <InputText @bind-Value="Address.PostalCode" /> <ValidationMessage For="@(() => Address.PostalCode)" /> </div> </div>
En el explorador de archivos, expanda Model y, después, seleccione Address.cs.
Agregue un mensaje de error personalizado para la anotación de datos de cada campo.
public class Address { public int Id { get; set; } [Required, MinLength(3, ErrorMessage = "Please use a Name bigger than 3 letters."), MaxLength(100, ErrorMessage = "Please use a Name less than 100 letters.")] public string Name { get; set; } [Required, MinLength(5, ErrorMessage = "Please use an Address bigger than 5 letters."), MaxLength(100, ErrorMessage = "Please use an Address less than 100 letters.")] public string Line1 { get; set; } [MaxLength(100)] public string Line2 { get; set; } [Required, MinLength(3, ErrorMessage = "Please use a City bigger than 3 letters."), MaxLength(50, ErrorMessage = "Please use a City less than 50 letters.")] public string City { get; set; } [Required, MinLength(3, ErrorMessage = "Please use a Region bigger than 3 letters."), MaxLength(20, ErrorMessage = "Please use a Region less than 20 letters.")] public string Region { get; set; } [Required, RegularExpression(@"^([0-9]{5})$", ErrorMessage = "Please use a valid Postal Code with five numbers.")] public string PostalCode { get; set; } }
Prueba de las nuevas validaciones de anotación de datos
En Visual Studio Code, presione F5 o seleccione Ejecutar>Iniciar depuración.
El formulario de dirección muestra dinámicamente un mensaje de error debajo de un campo que tiene datos no válidos. Esta interacción se produce en el lado cliente e impide que los clientes escriban direcciones no válidas.
Presione Mayús + F5 para detener la ejecución de la aplicación.
Restauración del mensaje de error general y deshabilitación del botón de envío
En el explorador de archivos, expanda Pages y, a continuación, seleccione Checkout.razor.
En el componente
EditForm
, agregue un parámetroOnInvalidSubmit
que llamará a un métodoShowError
.<EditForm Model=Order.DeliveryAddress OnValidSubmit=PlaceOrder OnInvalidSubmit=ShowError>
Agregue un método ShowError que actualice la propiedad
isError
.protected void ShowError() { isError = true; }
Cambie el método
PlaceOrder
para actualizar las propiedadesisError
yisSubmitting
.async Task PlaceOrder() { isError = false; isSubmitting = true; var response = await HttpClient.PostAsJsonAsync( $"{NavigationManager.BaseUri}orders", OrderState.Order); var newOrderId= await response.Content.ReadFromJsonAsync<int>(); OrderState.ResetOrder(); NavigationManager.NavigateTo($"myorders/{newOrderId}"); }
En Visual Studio Code, presione F5 o seleccione Ejecutar>Iniciar depuración.
El mensaje de error se muestra si el cliente intenta enviar un formulario no válido.
Presione Mayús + F5 para detener la ejecución de la aplicación.
Habilitación del botón de envío cuando todos los campos son correctos
¿Una mejor experiencia de usuario sería que un cliente no pudiera enviar un pedido hasta que no haya completado todos los campos? Vamos a cambiar la página de finalización de la compra para admitir este requisito. Cambie EditForm
para usar EditContext en lugar de un modelo.
En el explorador de archivos, expanda Pages y, a continuación, seleccione Checkout.razor.
Actualice el elemento
EditFrom
.<EditForm EditContext=editContext OnValidSubmit=PlaceOrder>
Cambie el elemento de botón para usar el parámetro
isError
.<button class="checkout-button btn btn-warning" type="Submit" disabled=@isError>
En el bloque
@code
, agregue una declaración para el nuevo componenteEditContext
.private EditContext editContext;
Inicialice el contexto con la dirección de entrega del pedido.
protected override void OnInitialized() { editContext = new(Order.DeliveryAddress); editContext.OnFieldChanged += HandleFieldChanged; }
Este código también permite los vínculos de un controlador de eventos para cuando se cambia un área. En el nuevo controlador, puede comprobar si el modelo es válido y establecer
isError
correctamente.private void HandleFieldChanged(object sender, FieldChangedEventArgs e) { isError = !editContext.Validate(); StateHasChanged(); }
Dado que ahora hemos creado un controlador de eventos, debemos desecharlo cuando el componente de finalización de la compra ya no lo necesite.
public void Dispose() { editContext.OnFieldChanged -= HandleFieldChanged; }
Para implementar la característica
Dispose
, también debe informar a Blazor. Agregue este código al comienzo de la página, debajo de las instrucciones@inject
.@implements IDisposable
Elimine todas las referencias a
isSubmitting
y actualice el métodoPlaceOrder
.async Task PlaceOrder() { var response = await HttpClient.PostAsJsonAsync(NavigationManager.BaseUri + "orders", OrderState.Order); var newOrderId= await response.Content.ReadFromJsonAsync<int>(); OrderState.ResetOrder(); NavigationManager.NavigateTo($"myorders/{newOrderId}"); }
En Visual Studio Code, presione F5 o seleccione Ejecutar>Iniciar depuración.
Ahora se pide al cliente que escriba información y, para empezar, el botón Place order (Hacer pedido) está deshabilitado. Solo después de que todos los campos obligatorios tengan datos, se podrá hacer clic en el botón.
Presione Mayús + F5 para detener la ejecución de la aplicación.