
Estaba elaborando un artículo sobre autenticación/autorización, pero reparé que es mejor primero hacer uno completo como tutorial introductorio sobre ASP .NET MVC. Sé que hay muuuuchos artículos en la web sobre esto, pero en este trato de darle un estilo particular y un orden que no encontré en otros. Aquí vamos entonces con un primer acercamiento a esta maravillosa tecnología.
Un poco de teoría
Definición
MVC son las siglas de Model View Controller, o Modelo Vista Controlador en español. Es un patrón de arquitectura de software que se ha vuelto muy común en estos años, pero sus orígenes se remontan a la década del 70. Lo que propone este patrón es la separación de la interfaz de usuario con lógica de negocio y el manejo de los datos. Para esto se divide en 3 componentes:
- Modelo. Es el componente que se encarga de modelar, valga la redundancia, los datos del sistema: acceso y persistencia de la información que maneja el aplicativo.
- Vista. Es el componente que sirve de interfaz hacia los usuarios. Muestra el resultado del procesamiento hecho por el Controlador.
- Controlador. Es el encargado de recibir las peticiones y procesarlas, apoyándose en el Modelo y mostrando los resultados usando la Vista.
Implementación de Microsoft
Hay muchos frameworks para diferentes tecnologías de desarrollo que implementan MVC. Tenemos como ejemplos a Symfony para PHP, Struts para Java, Ruby on Rails para Ruby; entre otros que seguramente has escuchado o conoces.
Con respecto a ASP .NET, la implementación de Microsoft no es la primera, existen otros anteriores como MonoRail o Maverick .NET, por poner sólo un par de ejemplos. Fue en el año 2009 cuando Microsoft lanzó la versión 1.0 de su framework. Desde entonces, le ha dado bastante impulso a esta tecnología y ha sacado sucesivas versiones hasta llegar a la 5.2, lanzada en Julio del 2014.
Es de destacar también que esta tecnología es Open Source, es decir, el código fuente es accesible desde CodePlex, lo que significa que puedes descargarlo y modificarlo a tu gusto, e incluso puedes hacer contribuciones al equipo de desarrollo de Microsoft para que lo incorporaren al proyecto, si ellos lo consideran por supuesto. Más información en la página oficial del proyecto.
ASP .NET MVC y ASP .NET WebForms
Cuando salió MVC, la tecnología existente en el mundo web de DotNet era ASP .NET WebForms. Este acontecimiento significó una revolución y surgieron muchas dudas acerca de cuál tecnología era mejor. En resumen, cada una tiene sus ventajas y desventajas, y depende del escenario en que estés para poder decidirte por una u otra, aunque con ventaja para MVC desde mi punto de vista.
WebForms
Ventajas:
- Es más rápida para desarrollar y más simple, ya que la tecnología oculta el protocolo HTTP (sin estado) emulando el desarrollo de aplicaciones de escritorio, orientado a eventos y con manejo de estado.
- La curva de aprendizaje es pequeña, ya que no se necesita conocer el ciclo de funcionamiento del protocolo HTTP, los comandos GET, POST u otros; además que no es necesario (casi) usar Javascript.
Desventajas:
- La simplificación tiene un costo, ya que las páginas resultantes son bastantes pesadas, debido a la complejidad que se esconde y el manejo de estado que se encapsula en controles ocultos.
- No se tiene control del HTML generado, lo que hace bastante complicado incorporar algo de código cliente (Javascript).
- Debido al code-behind (código de cada página web) es muy complicado que el código contenido en estas páginas sea reutilizable o pueda ser sometido a pruebas (TDD).
MVC
Ventajas:
- Al estar separados los componentes en el proyecto, lo hacen más ordenado, reutilizable e ideal para ejecutar pruebas (TDD) de los procedimientos.
- Al tener un control total del HTML generado, las páginas están más optimizadas, es decir, son más ligeras. Además, son ideales para usar Javascript, en concordancia con las tecnologías actuales donde han tomado gran importancia librerías como Prototype, JQuery, entre otras.
- Posee un excelente sistema de enrutamiento, más simple de recordar y SEO friendly (amigables con el posicionamiento en buscadores).
Desventajas:
- La principal desventaja de esta tecnología es su curva de aprendizaje, especialmente si vienes del mundo Windows Forms o similares.
Un poco de práctica
Vamos a crear nuestro primer proyecto ASP .NET MVC. Empezaremos con algo simple para fijar conceptos. Para este ejemplo he usado el IDE Visual Studio 2013, pero también puedes usar las versiones Express (más información aquí). En el programa creamos un Nuevo proyecto de tipo Web:

Seleccionamos la plantilla MVC:

Cuando hagamos click en Cambiar autenticación nos aseguramos que esté en Sin autenticación (recordemos que queremos hacer un ejemplo simple):

Entonces creamos el proyecto con la plantilla seleccionada, cuando termine nos aparecerá el aplicativo listo para usar:

Revisando el proyecto creado
Haciendo una revisión de la estructura de archivos creada, podemos ver que quedó así:

El nombre de cada carpeta explica más o menos su uso, de todas maneras haré un comentario por cada una:
- App_Start contiene el código de inicialización y configuración del aplicativo, por ejemplo el enrutamiento.
- Content para el contenido css, imágenes y otros archivos que usarán las vistas.
- Controller para los controladores a usar.
- Models contiene las clases que componen el modelo del aplicativo.
- Scripts contiene los archivos y librerías Javascript (ASP .NET MVC trae de serie la librería JQuery).
- Views contiene las vistas. Para nuestro ejemplo en formato .cshml y con el motor de renderización Razor.
Sobre la primera carpeta, App_Start, es importante explicar la clase RouteConfig. En MVC, la gestión de las solicitudes del navegador no se hace a través de archivos físicos (aspx, html), sino a través de acciones de un controlador. Dado que las peticiones, expresadas en rutas lógicas, irán dirigidas a una acción de un controlador, siempre sabremos que vista usaremos para cada caso. El archivo RouteConfig.cs contiene lo siguiente:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace IntroduccionASPNETMVC { public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } } }
En esta clase se registra la tabla de rutas. Para nuestro caso la URL del aplicativo tendrá la siguiente estructura: {controller}/{action}/{id}.
También se define que el controlador por defecto es Home, la acción es Index y el código será vacío, por lo que cuando accedamos al aplicativo sin definir estos valores, sólo con la ruta http, de esta manera:
- http://localhost:55753
El aplicativo nos remitirá al controlador y acción definidos por defecto. Es decir, internamente la ruta que se accede es:
- http://localhost:55753/Home/Index
Usando la Fuerza
Vamos a crear un Modelo, Controlador y Vista propios para este ejemplo. Comenzamos por lo primero, creamos las clases Jedi y JediContext para nuestro modelo (sí, soy seguidor de Star Wars) en la carpeta Models.
- La primera clase (Jedi) define la entidad que manejaremos en el modelo. Añadimos unas cuantas propiedades a la clase, acordes a nuestro negocio:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace IntroduccionASPNETMVC.Models { public class Jedi { public int ID { get; set; } public string Nombre { get; set; } public string Rango { get; set; } public string ColorEspada { get; set; } public int ConteoMidiclorias { get; set; } } }
- La segunda (JediContext) es una clase de apoyo, desde donde retornamos una lista de Jedis. Para nuestro ejemplo no accedemos a ninguna base de datos, instanciamos 3 objetos y los devolvemos en una colección. Este tipo de clases las explicaré posteriormente en otro post que trate en detalle el tema Acceso a Datos o Entity Framework:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Entity; namespace IntroduccionASPNETMVC.Models { public class JediContext : DbContext { public JediContext() : base("Jedi") { } public ListJedis { get { var jedis = new List { new Jedi{ ID = 1, Nombre = "Mace Windu", ColorEspada = "Morado", Rango = "Maestro ", ConteoMidiclorias = 10000 }, new Jedi{ ID = 2, Nombre = "Obi-Wan Kenobi", ColorEspada = "Celeste", Rango = "Caballero", ConteoMidiclorias = 15000 }, new Jedi{ ID = 3, Nombre = "Anakin Skywalker", ColorEspada = "Azul", Rango = "Padawan ", ConteoMidiclorias = 20000 } }; return jedis; } set { } } } }
Luego del modelo, vamos por el controlador:


Para poner el nombre del controlador, debemos seguir la nomenclatura [nombre_controlador]Controller:

En nuestro controlador recién creado agregamos la acción Listado (posteriormente se creará una vista del mismo nombre). Lo que hará esta acción es instanciar la clase de contexto (JediContext) que retornará un listado de Jedis, para luego enviar esta información a la Vista. El código queda así:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using IntroduccionASPNETMVC.Models; namespace IntroduccionASPNETMVC.Controllers { public class JediController : Controller { private JediContext db = new JediContext(); public ActionResult Listado() { return View(db.Jedis.ToList()); } } }
El siguiente paso es crear la Vista. En el controlador seleccionamos la acción Listado y le damos click derecho para crear la vista:

Ponemos los datos de la vista. Seleccionamos la clase de modelo y de contexto (Jedi y JediContext respectivamente):
Vemos que en la carpeta Views se ha creado una subcarpeta Jedi, y dentro un archivo Listado.cshtml, que corresponde a la vista:

El contenido de la vista generada es:
@model IEnumerable@{ ViewBag.Title = "Listado"; Layout = "~/Views/Shared/_Layout.cshtml"; } Listado
@Html.ActionLink("Create New", "Create")
@foreach (var item in Model) { @Html.DisplayNameFor(model => model.Nombre) @Html.DisplayNameFor(model => model.Rango) @Html.DisplayNameFor(model => model.ColorEspada) @Html.DisplayNameFor(model => model.ConteoMidiclorias) } @Html.DisplayFor(modelItem => item.Nombre) @Html.DisplayFor(modelItem => item.Rango) @Html.DisplayFor(modelItem => item.ColorEspada) @Html.DisplayFor(modelItem => item.ConteoMidiclorias) @Html.ActionLink("Edit", "Edit", new { id=item.ID }) | @Html.ActionLink("Details", "Details", new { id=item.ID }) | @Html.ActionLink("Delete", "Delete", new { id=item.ID })
Como vemos la vista contiene básicamente código HTML, pero se mezcla con algo de código de servidor, el cual tiene el prefijo @. Este código se interpreta usando el motor de renderización Razor, que se eligió por defecto al momento de crear el proyecto. En la primera línea se define un IEnumerable para la clase Jedi, esto nos sirve para recorrer ese conjunto de datos e ir «pintándolo» en cada fila de la tabla, a partir de la línea 30. ¡Eso es control total sobre el HTML generado!
Es importante destacar los Html Helpers que aparecen en el código, son los que empiezan por @Html. Por ejemplo, en la instrucción @Html.DisplayNameFor(model => model.Rango) lo que se hace es «pintar» el nombre del atributo Rango en el modelo que se maneja, es decir de la clase Jedi.
El Helper @Html.DisplayFor(modelItem => item.Rango) funciona de la misma manera, pero genera un cuadro de texto, o mejor dicho un control HMTL input del tipo text.
Vamos a eliminar los helper @Html.ActionLink, ya que en este ejemplo simple sólo queremos mostrar el listado. La vista quedaría así:
@model IEnumerable@{ ViewBag.Title = "Listado"; Layout = "~/Views/Shared/_Layout.cshtml"; } Listado
@foreach (var item in Model) { @Html.DisplayNameFor(model => model.Nombre) @Html.DisplayNameFor(model => model.Rango) @Html.DisplayNameFor(model => model.ColorEspada) @Html.DisplayNameFor(model => model.ConteoMidiclorias) } @Html.DisplayFor(modelItem => item.Nombre) @Html.DisplayFor(modelItem => item.Rango) @Html.DisplayFor(modelItem => item.ColorEspada) @Html.DisplayFor(modelItem => item.ConteoMidiclorias)
Finalmente, para probar nuestro aplicativo modificamos la línea 19 del archivo RouteConfig.cs, de la siguiente manera:
defaults: new { controller = "Jedi", action = "Listado", id = UrlParameter.Optional }
Lo que estamos haciendo es definir que la ruta por defecto del aplicativo sea Jedi/Listado.
Compilamos el proyecto y lo ejecutamos, obteniendo el resultado final de nuestro proyecto:

Reflexión final
En este artículo quise abordar de manera genérica un proyecto ASP .NET MVC, por lo que no se profundizó en algunos temas como Autenticación/Autorización, acceso a datos con o sin Entity Framework, motor de renderización Razor, enrutamiento, Helpers, entre otros. Estos temas lo dejaremos para artículos posteriores, ya que son muy interesantes y merecen, cada uno de ellos, un post completo.
Sólo queda que te ejercites en esta tecnología, creando proyectos MVC y practicando lo más que puedas lo aprendido en este y otros artículos. Pues en esto, como en todo, la práctica hace al maestro.