13 - Validación de datos de formularios HTML- Html.ValidationMessageFor

Una actividad fundamental antes de almacenar los datos en una base de datos es controlar si los mismos son correctos, y en caso de no ser correctos informar al usuario cuales fueron cargados en forma incorrecta.

Las validaciones las podemos hacer en forma manual cuando recuperamos los datos de un formulario o utilizar las herramientas propuestas por ASP.Net MVC que consiste en definir reglas de validaciones en el "Modelo" y Helpers HTML para mostrar los mensajes de error en la "Vista".

Problema (Proyecto13)

Declarar un modelo que represente una persona y definir las reglas de validación en cada propiedad mediante Data Annotations:

Persona.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace Proyecto13.Models
{
    public class Persona
    {
        [Required(ErrorMessage = "El Nombre es obligatorio")]
        [MinLength(10, ErrorMessage = "El Nombre de usuario debe tener al menos 10 caracteres")]
        public String Nombre { get; set; }

        [Range(1, 18, ErrorMessage = "La edad debe estar entre 1 y 18")]
        public int Edad { get; set; }

        [EmailAddress(ErrorMessage = "Debe ingresar un mail válido")]
        public String Email { get; set; }

        [RegularExpression("[MmFf]", ErrorMessage = "Solo puede ingresar una M o F")]
        public String Genero { get; set; }
    }
}

Los atributos de anotaciones de datos se declaran previo al nombre de la propiedad encerrado entre corchetes.
Si queremos que una propiedad se cargue por teclado en forma obligatorio definimos "Required" y entre paréntesis iniciamos la propiedad ErrorMenssage con el texto a mostrar en la vista si el operador no carga nada en el control:

        [Required(ErrorMessage = "El Nombre es obligatorio")]
        [MinLength(10, ErrorMessage = "El Nombre de usuario debe tener al menos 10 caracteres")]
        public String Nombre { get; set; }

Como vemos podemos definir varias reglas de validación para la misma propiedad.

Para poder definir atributos de anotaciones de datos debemos importar:

using System.ComponentModel.DataAnnotations;

Las anotaciones más comunes que podemos utilizar son:

  • Required: Indicamos que la propiedad no puede estar vacía.
  • Range: Definimos el valor mínimo y máximo de la propiedad numérica.
  • EmailAddress: Valida que el email tenga un formato correcto.
  • MinLength: Definimos el mínimo número de caracteres que debe cargarse.
  • ManLength: Definimos el máximo número de caracteres que debe cargarse.
  • RegularExpression: Definimos una expresión regular que debe cumplir la propiedad.
  • CustomValidation: Especificamos un método de validación que codificamos nosotros.

Ahora creamos el HomeController y definimos dos acciones:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Proyecto13.Models;

namespace Proyecto13.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            Persona per = new Persona();
            return View(per);
        }

        [HttpPost]
        public ActionResult Index(Persona per)
        {
            if (ModelState.IsValid)
                return View("Correcto");
            else
                return View(per);
        }
    }
}

También debemos definir la vista "Index.cshtml":

@model Proyecto13.Models.Persona

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div>
        @using (Html.BeginForm())
        {
            <p>
                Ingrese Nombre:
                @Html.EditorFor(model => model.Nombre)
                @Html.ValidationMessageFor(model => model.Nombre)
            </p>
            <p>
                Ingrese Edad (entre 1 y 18):
                @Html.EditorFor(model => model.Edad)
                @Html.ValidationMessageFor(model => model.Edad)
            </p>
            <p>
                Ingrese Email:
                @Html.EditorFor(model => model.Email)
                @Html.ValidationMessageFor(model => model.Email)
            </p>
            <p>
                Ingrese género:
                @Html.EditorFor(model => model.Genero)
                @Html.ValidationMessageFor(model => model.Genero)
            </p>
            <p>
                <input type="submit" value="Confirmar" />
            </p>
        }
    </div>
</body>
</html>

Mostramos cada uno de los controles HTML utilizando el método EditorFor y mediante el método ValidationMessageFor mostramos el mensaje de error en caso de no cumplirse la validación definida en el "Modelo".

Cuando iniciamos la aplicación se ejecuta la vista "Index.cshtml" y se le pasa una variable de tipo Persona:

        public ActionResult Index()
        {
            Persona per = new Persona();
            return View(per);
        }

Al presionar el botón de tipo submit se ejecuta la acción:

        [HttpPost]
        public ActionResult Index(Persona per)
        {
            if (ModelState.IsValid)
                return View("Correcto");
            else
                return View(per);
        }

Si la propiedad IsValid del objeto ModelState almacena un true significa que todos los datos ingresados en el formulario se validaron correctamente para todas las reglas que definimos en el modelo. Aquí es donde podemos por ejemplo registrar los datos en la base de datos.

En el caso que alguna de las validaciones no se cumple se ejecuta el else del if cargando nuevamente la vista "Index.cshtml" y con esto aparecen los mensajes de las validaciones que no se cumplen:

Validaciones en ASP.Net MVC

La última vista que debemos codificar es la "Correcto.cshtml":


@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Correcto</title>
</head>
<body>
    <div>
        <p>Los datos fueron cargados correctamente.</p>
        @Html.ActionLink("Retornar", "Index")
    </div>
</body>
</html>

Este proyecto lo puede descargar en un zip desde este enlace: proyecto13.zip