En esta ocasión les traigo un post acerca de una parte importante de una aplicación asp.net MVC, las vistas.

El problema

Es común entre los desarrolladores web el emplear un framework de CSS para el estilo visual de su aplicación, en este caso hablaremos puntualmente de Bootstrap, el cual está bastante extendido entre los desarrolladores .net. El problema radica en que al utilizar los HtmlHelpers incluidos en el framework nuestras vistas, incluso las más simples pueden terminar así:

Como pueden ver, hay gran cantidad de código HTML repetido y muy propenso a ser difícil de mantener si deseamos hacer cambios tanto en los tamaños (columnas de Bootstrap) o incluso si deseáramos cambiar de framework CSS. Esto en una aplicación grande representa un gran riesgo.

Solución

Vamos a refactorizar nuestras vistas creando nuestros propios métodos de extensión, nuestros HtmlHelpers para poder renderizar nuestros controles de Bootstrap mas fácilmente.

Creación de las clases bases

  1. Creamos una carpeta en nuestra solución para guardar las clases que nos ayudaran a crear nuestros helpers. En mi caso la llamare HTML y estará ubicada dentro de otra carpeta en la raíz llamada Infraestructure.
    Folder

  2. A continuación agregaremos una clase llamada FormControl. Esta representara un control de formulario estilizado con Bootstrap, el cual yo he abstraído de la siguiente manera (He agregado una imagen para clarificar el porqué de las propiedades en mi modelo).
    Abstracción

  3. La clase FormControl quedaría de la siguiente forma.

  1. Ahora para facilitar la configuración de los tamaños de las columnas de Bootstrap crearemos la siguiente struct para representar un tamaño de Bootstrap, que como sabrán se compone de 4 componentes col-lg-* ,col-md-* ,col-sm-* y col-xs-*. En la cual además he agregado la pequeña lógica para calcular el tamaño complementario que ocupe las 12 columnas de Bootstrap.
  1. Ahora crearemos la vista que utilizaremos como plantilla para renderizar nuestros controles de formulario con Bootstrap, la cual estará ubicada en /Views/Shared/Controls/ llamada FormControl.cshtml.

Creación del método de Extensión

Y finalmente la parte más importante, la creación del helper HTML, el cual básicamente es un método de extensión para la clase HtmlHelper o HtmlHelper<T> (si deseas saber más al respecto puedes dirigirte al siguiente link).

  1. Primero agregamos una clase llamada BootstrapHelpers, la cual debe ser estática.

      public static class BootstrapHelpers
      {
      }
    
  2. Definimos algunas constantes que necesitamos para renderizar nuestro control. Como la ubicación de nuestras plantillas, la clase que debe tener los labels y la clase que deben tener los inputs.

      public static class BootstrapHelpers
      {
          private const string PartialBaseFolder = "~/Views/Shared/Controls/";
         private const string LabelClass = "control-label";
         private const string InputClass = "form-control";
      }
    
  3. Ahora definimos nuestro método BootstrapTextboxFor.

     public static MvcHtmlString BootstrapTextboxFor<T,TValue>
         (this HtmlHelper<T> helper,
         Expression<Func<T,TValue>> property,
         Size controlSize)
    

El primer parámetro HtmlHelper helper es marcado con this para que sea un método de extensión. El segundo parámetro es la expresión que nos permite saber a qué propiedad nos referimos y el tercer y último parámetro nos permite configurar el tamaño de nuestro control.

  1. Lo primero que hacemos es calcular el tamaño del label como el complemento del tamaño de nuestro input. Y así tenemos el tamaño del control y de nuestro label, a lo cual agregamos la clase que debe tener para mostrarse correctamente en Bootstrap.

     var labelSize = controlSize.GetComplement().ToString();
     var containerSize = controlSize.ToString();
     var labelClasses = $"{LabelClass} {labelSize}"; 
    
  2. Con estos datos, creamos nuestra instancia de FormControl de la siguiente manera.

     var control = new FormControl()
     {
       Label = helper.LabelFor(property,new {@class=labelClasses}),
       Control = helper.TextBoxFor(property, new { @class = InputClass }),
       ContainerSize = containerSize,
       Validation = helper.ValidationMessageFor(property)
     };
    
  3. Con esta instancia renderizamos nuestro control con ayuda de la vista parcial que usamos de plantilla.

     return helper.Partial(PartialBaseFolder+"FormControl.cshtml", control);
    
  4. Finalmente, el método de extensión quedaría de la siguiente forma.

Probemos lo construido

Es momento de probar lo que hemos construido, primero recordemos como se veía la vista antes.

Ahora, lo primero que haremos para usar nuestro método es definir el tamaño de nuestro control como una variable, podemos aprovechar el bloque donde definimos el título.

@{
    ViewBag.Title = "Nuevo";
    var controlSize = new Size(10,10,6,12);
}

Agregamos también el @using RefactorView.Infraestructure.Html en el inicio de nuestra vista, recuerden que si quieren evitar este paso, pueden editar el web.config que se encuentra dentro de la carpeta Views y agregar este espacio de nombres.

Continuando con nuestra vista, podemos ahora remplazar todo ese extenso HTML por la siguiente vista.

Conclusiones

Como pueden ver, a veces será necesario refactorizar incluso nuestras vistas para asegurarnos que estamos creando una aplicación mucho más mantenible en el tiempo, la cual es así mismo mucho más legible y entendible. Espero les haya gustado este post. Seguiremos trabajando en los métodos de extensión en los siguientes post.

Recuerda que puedes descargar el proyecto con el codigo en este repositorio en github github.