This article has been localized into Spanish by the community.
Validación del Modelo por el lado del Cliente
Hasta aquí, todas la validaciones de Modelo que hemos usado en este tutorial se han hecho por el lado del servidor. Esto significa que el modelo se devuelve al servidos donde la validación se lleva a cabo considerando tus "Data annotations" y el resultado es devuelto al usuario. Esto es bueno y malo:
Es bueno porque no puedes confiar en la validación por el lado del cliente - el usuario puede simplemente cambiar o sortear cualquier validación hecha en el cliente. En otras palabras, siempre se necesita validar las cosas en el servidor para estar absolutamente seguro que todo está tal y como debiera ser.
Por el otro lado, el viaje de ida y vuelta extra hacia el servidor hace la validación un poco más lenta (o mucho, si hay retrasos en la comunicación entre el servidor y el cliente) y además eleva los requerimientos de recursos para tu aplicación web: Si muchos usuarios están accediendo a tu sitio web al mismo tiempo, se harán un montón más de validaciones extra en el servidor.
Entonces, para tener lo mejor de ambos mundos, primero deberías realizar la validación en el cliente - si se encuentra algún error, no deberás realizar la validación por el lado del server. En su lugar le dices al cliente lo que esta mal, así el podrá arreglarlo de inmediato. Por otra parte, si no se ha encontrado ningún error, realizas la validación por el lado del servidor también, para estar absolutamente seguro que todo está en orden.
Previamente, este enfoque de doble validación necesitaría que escribas código en ambos, C# (o cualquier lenguaje que utilices para el servidor) para el lado del servidor y JavaScript para el cliente. Esto era muy incomodo y podia fácilmente provocar inconsistencias. Afortunadamente para nosotros "ASP.NET Core" trató de resolver este problema para nosotros: Cuando usas "Data Annotations" para tus modelos, como se describe en artículos previos, y usas "TAG Helpers" o "HTML Helpers" para generar tus formas, el Framework generará automáticamente la validación de datos para estos elementos. Estos datos pueden ser usados por una librería de JavaScript, para la validación por el lado del cliente, creada por Microsoft sobre una librería de validación existente en JavaScript para jQuery.
Esto podría sonar complicado, pero es porque una validación buena y robusta ES una tarea complicada. Por lo tanto haré recorrido completo para mostrarte como puedes lograr ambas validaciones, tanto por el lado del server, como por el lado del cliente, en tu aplicación "ASP.NET MVC" usando el mismo modelo.
El Modelo
En nuestro ejemplo, haremos una FORMA para la creación de un nuevo perfil de usuario para nuestro sitio web imaginario. Primero, definiremos nuestro Modelo, llamado WebUser, que es muy simple. Usa "Data Annotations" en las propiedades más relevantes para indicar como debería ser validado este Modelo. y es así:
using System.ComponentModel.DataAnnotations;
namespace ClientSideValidation.Models
{
public class WebUser
{
[Required]
[StringLength(25)]
public string FirstName { get; set; }
[Required]
[StringLength(50, MinimumLength = 3)]
public string LastName { get; set; }
[Required]
[EmailAddress]
public string MailAddress { get; set; }
}
}
El Controlador
Tenemos un Controlador llamado UsersController - hasta ahora, solo tiene dos métodos y ambos se llaman Create(). Hay uno para la versión GET, el que simplemente servirá a la Vista, y luego está la version POTS, el que es llamado cuando la FORMA es enviada para crear el nuevo usuario. Verificará, automáticamente, si el modelo es válido gracias a los "Data Annotations" y retornará la Vista, esto se muestra en el siguiente recuadro:
using ClientSideValidation.Models;
using Microsoft.AspNetCore.Mvc;
namespace ClientSideValidation.Controllers
{
public class UsersController : Controller
{
[HttpGet]
public IActionResult Create()
{
return View();
}
[HttpPost]
public IActionResult Create(WebUser webUser)
{
if(ModelState.IsValid)
{
// Here the WebUser should be saved. Afterwards we would normally return another View, to
// indicate that the User has been successfully created, or redirect to another page
}
return View();
}
}
}
Lo más interesante es la verificación de la propiedad ModelState.IsValid. Esto es llenado automáticamente por el Framework, luego de que ha sido validada de acuerdo a tus "Data Annotations".
La Vista
La Vista es una Forma muy básica que soporta las propiedades de la clase WebUser. Usaremos "Tag Helpers" (están descritos en detalle en otra parte de este tutorial) para generar etiquetas, campos de entrada y salidas de validación - nota que poco "markup" necesitamos para lograr esto:
@model ClientSideValidation.Models.WebUser
@{
ViewData["Title"] = "Create";
}
<h1>Create user</h1>
<form method="post" asp-controller="Users" asp-action="Create">
<div>
<label asp-for="FirstName"></label><br />
<input asp-for="FirstName" />
<span asp-validation-for="FirstName" style="color: red;"></span>
</div>
<br />
<div>
<label asp-for="LastName"></label><br />
<input asp-for="LastName" />
<span asp-validation-for="LastName" style="color: red;"></span>
</div>
<br />
<div>
<label asp-for="MailAddress"></label><br />
<input asp-for="MailAddress" />
<span asp-validation-for="MailAddress" style="color: red;"></span>
</div>
<br />
<input type="submit" value="Create" />
</form>
Por favor ten en cuenta que, al momento de escribir esto, los "Tag Helpers" aún debían ser habilitados manualmente antes de que pudieras usarlos. Revisa nuestro artículo Using Tag Helpers para más información.
Gracias a los "Tag Helpers" (observa la propiedad asp-*) esto se ha vuelto una Forma, aunque básica, completa. Y debería verse como sigue:
Si revisas el código fuente HTML resultante, verás la cantidad de trabajo que realiza el Framework por nosotros:
<form method="post" action="/Users/Create">
<div>
<label for="FirstName">FirstName</label><br />
<input type="text" data-val="true" data-val-length="The field FirstName must be a string with a maximum length of 25." data-val-length-max="25" data-val-required="The FirstName field is required." id="FirstName" maxlength="25" name="FirstName" value="" /><br />
<span style="color: red;" class="field-validation-valid" data-valmsg-for="FirstName" data-valmsg-replace="true"></span>
</div>
<br />
<div>
<label for="LastName">LastName</label><br />
<input type="text" data-val="true" data-val-length="The field LastName must be a string with a minimum length of 3 and a maximum length of 50." data-val-length-max="50" data-val-length-min="3" data-val-required="The LastName field is required." id="LastName" maxlength="50" name="LastName" value="" /><br />
<span style="color: red;" class="field-validation-valid" data-valmsg-for="LastName" data-valmsg-replace="true"></span>
</div>
<br />
<div>
<label for="MailAddress">MailAddress</label><br />
<input type="email" data-val="true" data-val-email="The MailAddress field is not a valid e-mail address." data-val-required="The MailAddress field is required." id="MailAddress" name="MailAddress" value="" /><br />
<span style="color: red;" class="field-validation-valid" data-valmsg-for="MailAddress" data-valmsg-replace="true"></span>
</div>
<br />
<input type="submit" value="Create" />
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8C-7mCG55hBDrFHYMGeG3xGBvY_epwiSr_q_mFnFRpTKHxdV8s0kZB-v0LZtzzOrKOpTHvxPvb_4oukqQCBdOj3idVTMAiic9h-oZahWfai5LK6MOVbEpsiqyzyKAD89JX8O7YfiXSegLbcDZpHcQQI" />
</form>
Cuando presionas el botón "Create", la FORMA es enviada al método Create(WebUser) en el UserController. Será validada por el lado del servidor y luego la Vista será retornada, pero con salidas de validación visibles - todo esto sucede sin ningún esfuerzo extra, lo que es realmente bueno:
Sin embargo, en este punto, aún estamos usando la validación por el lado del servidor - cambiemos eso.
Agregando validación por el lado del Cliente
Ahora viene la parte buena! Ya que hemos sido muy cuidadosos al crear nuestro Modelo y nuestra Vista de la forma correcta, todo lo que necesitamos hacer para agregar la validación por el lado del cliente, es incluir un par de librerías JavaScript -el resto será manejado automáticamente porque hemos creado un Modelo con "Data Annotations" y nuestra FORMA con "Tag Helpers". Simplemente incluye la siguiente línea en tu Vista o tu archivo Layout, preferiblemente en la sección HEAD:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"></script>
Cuando recargues la página, te darás cuenta de algo genial: la validación se realiza automáticamente tan pronto como comienzas a llenar la FORMA y si presionas el botón Create, la FORMA es enviada al servidor solo si todo parece ser válido. Si lo es, y la FORMA es enviada de vuelta al servidor, ésta será validada por el lado del servidor de acuerdo a las mismas reglas que solo has especificado en un lugar. ¡Esta es realmente la belleza de unir los diversos componentes del Framework de "ASP.NET Core"!
Por favor ten en cuenta
- La primera línea es solo un jQuery regular del Framework - si ya has incluido esto en alguna otra parte, no necesitarás hacerlo nuevamente
- Todas las referencias aquí son para una CDN (Red de Entrega de Contenidos) específica - puedes escoger otra CDN o bajar los archivos y servirlos directamente desde tu sitio web
- Todas las referencias aquí son para una version específica (jQuery version 3.4.1 y mayor) - podrías querer revisar si existe una nueva version disponible
Sumario
Validar las entradas de usuario ha sido siempre una molestia - requiere un montón de esfuerzo y repetición de código, especialmente si buscas ambas validación por el lado del cliente y del servidor. Sin embargo, como se ha mostrado en este artículo, el Framework de "ASP.NET Core" hace esta tarea mucho mas fácil, rápida y robusta!