lunes, 9 de octubre de 2017

ASP.NET CORE–Validadores

Una de las características que tenemos disponible en aplicaciones ASP.NET desde hace más tiempo del que puedo recordar es el uso de validadores (Validators) para automatizar, en mayor o menor medida, las validaciones que siempre tenemos que realizar cuando enviamos información de un formulario al servidor.

Con la llegada de JQuery y sus extensiones JQuery.Validation y JQuery.Validation.Unobtrusive, la funcionalidad que proporcionan estos validadores mejoró en sus capacidades, ya que de manera automática (hasta donde yo sé) son capaces de realizar las validaciones en cliente antes de hacer el envío o post al servidor, haciendo que el rendimiento de la aplicación web no se resienta.

Reconozco que a mí no me habían gustado nunca, ya que les veía poca funcionalidad, poca flexibilidad y… bueno, que no me convencían. He decidido darles otra oportunidad en el ámbito de ASP.NET Core, porque lo cierto es que al final es muy probable que nos ahorren tiempo.

Primero quiero empezar con una captura de los validadores estándar que podemos encontrar en una aplicación ASP.Net Core:

image

Bastante feo, ¿no?

¿Cómo funcionan?

En el post sobre localización [acceso] ya estuvimos hablando sobre los DataAnnotations así que aquí no trabajaremos con localización, de momento una pequeña explicación de cómo funciona el sistema de validadores en ASP.NET Core.

Modelo:

En el modelo especificamos qué condiciones tiene que cumplir la propiedad para ser válida:

image

En el ejemplo anterior estamos indicando que la propiedad Email es obligatoria y que tiene que ser una dirección de correo ‘bien formada’. Estos atributos (normalmente en el namespace System.ComponentModel.DataAnnotations) se encargan automáticamente de realizar validaciones sobre los valores introducidos en la vista. Cuando el envío llega al controlador, la propiedad IsValid del ModelState indicará si los valores son correctos o no:

image

Aquí podemos ver que si el modelo no es valido, directamente vuelve a cargar la página, en la que veremos los validadores aplicados como se ven en la primera captura.

He dicho antes que los validadores se ejecutan en el cliente, pero en esta pequeña explicación sólo he hablado de la parte de servidor, lo he hecho así para poder hablar de la propiedad IsValid ya que nos puede servir también para operaciones avanzadas con el modelo una vez que estamos en la parte del servidor.

Cliente:

Para poder ejecutar esos validadores en el cliente tenemos que utilizar las librerías de Javascript JQuery.Validation y JQuery.Validation.Unobtrusive, que por suerte tenemos ya disponibles cuando creamos un proyecto de ASP.NET Core en Visual Studio:

image

Además, si entramos a la vista donde utilizamos los validadores, veremos al final de la misma como los scripts necesarios se incluyen mediante una vista parcial:

image

Esto es interesante ya que si queremos incluir nuestros propios scripts de validación, si añadimos la referencia en esta vista parcial, los tendremos disponibles automáticamente en el resto de vistas donde se utilicen los validadores estándar.

Para poder utilizar los validadores tenemos que añadirlos en la vista (tiene sentido ¿no?)

image

Como podemos ver, tenemos varios atributos asp-xxx que gestionan la validación:

  • asp-validation-summary define una sección con todos los errores encontrados.
  • asp-validation-for especifica una sección donde se mostrarán los errores encontrados para la propiedad del modelo indicada (en este ejemplo Email)

¿Cómo podemos saber que la validación funciona sólo en cliente?

Esta es fácil, basta con poner un punto de ruptura en la acción del controlador y ejecutar el proyecto, si ponemos valores incorrrectos en el formulario y hacemos el Post, veremos que NO llega ninguna petición al controlador, porque no llegaremos al punto de ruptura. De hecho, si alguna vez llegáis al servidor sin que se hayan evaluado las validaciones de cliente, tenéis un problema.

¿Esto es todo?

hasta ahora, todo lo que hemos visto es el comportamiento estándar de los validadores, pero siguen quedando como ‘feuchos’. Gracias a Bootstrap podemos hacer alguna adaptación que quede un poco más elegante, algo como esto (con iconos en las cajas):

image

Peeero, si queremos algo más avanzado, como mostrar los errores en una ventana modal (algo bastante habitual por otra parte) es cuando empiezan nuestros problemas.

Al turrón

Lo primero que hacemos es crear una vista parcial en la que ponemos el código del ‘esqueleto’ de la ventana modal que queremos mostrar:

image

A continuación incluimos esta vista parcial en la vista deseada (podríamos añadirla también en el _Layout para tenerla disponible en todas las vistas de la aplicación si nos interesa)

image

Lo siguiente que tenemos que hacer es preparar un script para que ‘capture’ el submit del formulario a validar y si hay errores muestre una ventana modal. El script en cuestión podría ser algo como esto (se trata de un ejemplo, no seáis muy duros):

image

En esta función lo que hacemos es codificar el submit del formulario, lanzamos las validaciones que tenga configuradas, y si hay algún error en esas validaciones, mostramos la ventana modal evitando que se continúe con el envío del formulario. En este ejemplo nos quedamos sólo con el último error detectado, pero creo que como ejemplo es suficiente.

Por supuesto este script tendremos que añadirlo en la página, si no, pues no se iba a ejecutar…

Si a continuación probamos el funcionamiento, tendremos esto:

image

Como podéis ver en la captura se siguen mostrando los errores de los validadores por defecto, si queremos evitarlo basta con quitar los validadores de la vista, ya que en las pruebas realizadas parece que no es necesario que estén físicamente en la página para que se realice la validación.

Conclusión

Me da la sensación de que interceptar las validaciones que se realizan por defecto puede acabar dándonos algún problemilla, pero lo cierto es que si queremos hacer algo diferente a los mensajes por defecto esta sería la aproximación que yo recomendaría.

No hay comentarios: