ASP.NET MVC

Autor: Daniel Mossberg, https://blogs.msdn.com/b/daniem

En marzo de 2009 se hizo pública la primera versión de ASP.NET MVC. El patrón de arquitectura MVC (model-view-controller) no es nuevo (data de 1979) ni es algo que haya inventado Microsoft. Existen muchos frameworks de desarrollo web populares que utilizan MVC, como por ejemplo Ruby on Rails, Spring o Apache Struts. MVC es un patrón de arquitectura que ayuda a crear una separación lógica entre el modelo (la lógica de acceso a datos), la vista (la lógica de presentación) y el controlador (la lógica de negocio).

Uno de los pilares básicos de ASP.NET MVC es el concepto de enrutamiento (routing), lo que permite a las aplicaciones aceptar peticiones a URLs que no se corresponden con ficheros físicos en el servidor. Por ejemplo, en ASP.NET Web Forms las URLs tienen el siguiente formato “http://website/products.aspx?category=dvd” en el que físicamente existe un fichero products.aspx en la raíz del sitio web. En MVC la misma URL tendría el siguiente aspecto “http://website/products/dvd” sin que el servidor web necesariamente contenga una carpeta products con una subcarpeta dvd. De forma predeterminada, ASP.NET MVC enruta las peticiones al controlador y a la vista adecuada en función de la URL. Es decir, en el ejemplo anterior, nos devolverá la vista dvd del controlador products.

Este es el aspecto que tiene un proyecto ASP.NET MVC en Visual Studio, que para quién haya trabajado en proyectos Web Forms notará cambios significativos:

El controlador es la pieza responsable de responder a las peticiones realizadas contra la aplicación ASP.NET MVC mediante distintas “acciones”, por ejemplo devolviendo una vista determinada, redireccionando la petición a un controlador distinto, etc. En el caso más básico, las acciones de un controlador se limitan a devolver vistas. En el siguiente ejemplo, el controlador products implementa dos acciones que devuelven las vistas index y dvd.

 

using System.Web.Mvc;

namespace AdventureWorks.Controllers
{
    public class ProductsController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to AdventureWorks online store!";

            return View();
        }

        public ActionResult Dvd()
        {            
            return View();
        }

    }
}

Para entender mejor el concepto de enrutamiento y su relación con controladores y vistas, analicemos que ocurre si añadimos una nueva acción bluray al controlador products que quedaría expuesta en la URL http://website/products/bluray.

public ActionResult Bluray()
{
    return View();
}

Si no indicamos lo contrario, ASP.NET MVC intentará buscar una vista que se llama igual que la acción que se ha ejecutado. El error que devuelve la aplicación indica que no ha podido encontrar la vista y además indica donde la ha buscado. Como se puede observar, en ASP.NET MVC hay un mapeo directo entre las URLs, los métodos que se ejecutan en el controlador (las acciones) y las vistas que se devuelven. Prevalece la convención sobre la configuración.

ASP.NET MVC fue concebido con el objetivo de proporcionar una mayor separación de conceptos y mayor control sobre el comportamiento de la aplicación. Al no hacer uso de muchos de los mecanismos de abstracción de ASP.NET Web Forms, como el view state o los formularios de servidor, ASP.NET MVC requiere un mayor conocimiento sobre protocolos y lenguajes web. En general las aplicaciones ASP.NET MVC requieren desarrollar una mayor cantidad de código que una aplicación ASP.NET Web Forms de funcionalidad equivalente, pero también proporcionan un mayor control al desarrollador sobre el comportamiento de la aplicación.

Cinco razones por las que ASP.NET MVC puede ser la mejor opción para ti

1 – Aplicaciones fácilmente integrables con pruebas unitarias

La principal característica que hace a una aplicación fácil de probar es el desacoplamiento (loose coupling) entre los componentes de la aplicación, de forma que cada uno de los componentes se pueda probar de forma aislada. Las pruebas unitarias en esencia son clases creadas con el único propósito de instanciar y hacer uso de las clases y métodos de una aplicación, y verificar que esas clases se comportan como es esperado en distintas situaciones. ¿El método X devuelve el valor esperado al pasar unos parámetros determinados? ¿La clase Y lanza una excepción de tipo Z cuando se pasan unos parámetros inválidos al constructor?

Uno de los grandes problemas de Web Forms era la imposibilidad de probar las aplicaciones mediante pruebas unitarias, dado que no es posible instanciar clases que heredan de System.Web.UI.Page de forma aislada. Sin embargo en ASP.NET MVC la lógica que controla el flujo de la aplicación reside en los controladores, y los controladores no son más que clases sin dependencias externas por lo que se pueden instanciar sin problemas desde el código de las pruebas unitarias. Siguiendo con el ejemplo anterior, podríamos implementar el siguiente método de prueba unitaria para verificar que el nombre de la vista que devuelve la acción Dvd del controlador Products es la esperada:

using System.Web.Mvc;
using AdventureWorks.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace AdventureWorksTest
{
    [TestClass]
    public class ProductsControllerTest
    {        
        [TestMethod]
        public void TestDvdView()
        {
            //Arrange
            ProductsController products = new ProductsController();

            //Act
            ViewResult result = (ViewResult)products.Dvd();

            //Assert
            Assert.AreEqual("Dvd", result.ViewName);
        }
    }
}

La plantilla de Visual Studio para crear un nuevo proyecto ASP.NET MVC es la única plantilla de un proyecto web que crea un proyecto adicional de pruebas unitarias en la solución, lo que de nuevo refuerza que las pruebas unitarias son una parte integral de las aplicaciones ASP.NET MVC.

2 – Mayor flexibilidad y control sobre las URLs expuestas por la aplicación.

ASP.NET MVC proporciona mayor control y flexibilidad sobre las URLs que expone la aplicación. El componente clave que posibilita esta funcionalidad de MVC es el motor de URL routing que se introdujo en ASP.NET 3.5 SP1, y que desde ASP.NET 4.0 también está disponible para Web Forms. El URL routing permite a las aplicaciones exponer URLs más simples, semánticamente más significativas para los usuarios y mejor optimizadas para los motores de búsqueda.

Las rutas predeterminadas en una aplicación ASP.NET MVC están definidas en el método RegisterRoutesdel fichero global.asax:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
    );
}

El enrutamiento predeterminado de cualquier aplicación ASP.NET MVC expone URLs del tipo http://website/{controlador}/{vista}/{parametros}. Por ejemplo, un controlador Search que realiza búsquedas en un catalogo de productos con una única vista Results a la que se pasa por parámetro la cadena de búsqueda por defecto estaría expuesta en la URL http://website/search/results/star+wars. Podría tener más sentido eliminar el nombre de la vista para conseguir una URL más simple, de forma que se accediera mediante http://website/search/star+wars. Conseguir esto únicamente requiere registrar una nueva ruta en el método RegisterRoutes:

routes.MapRoute(
    "Search", // Route name
    "Search/{id}", // URL with parameters
    new { controller = "Search", action = "Results"} // Parameter defaults
);

3 – Mayor control sobre el HTML de la aplicación.

En ASP.NET MVC desaparecen los controles de servidor basados el modelo de post-back de Web Forms dado que ahora cada interacción del usuario debe ir enrutada a un controlador y a una acción específicos. En la práctica esto implica que desaparecen la mayoría de controles de servidor que generan HTML, por lo que ahora es tarea de los desarrolladores escribir todo ese HTML. Esto supone varias ventajas importantes, una de ellas es que el HTML que producen las aplicaciones MVC es completamente predecible, los elementos HTML no tienen identificadores generados dinámicamente del tipo “ctl00_ControlPadre_ControlHijo_...” y por consecuencia es significativamente más sencilla la programación de código JavaScript de cliente contra el HTML generado. Otras ventajas son el control total a la hora de producir HTML validable, HTML compatible con distintos estándares de accesibilidad web, etc.

4 – Plataforma completamente extensible

ASP.NET MVC ha sido diseñada para ser completamente extensible, lo que implica que cualquier elemento lógico del flujo de procesamiento de una petición MVC, puede ser extendido o completamente sustituido por una implementación propia. Para ello, ASP.NET MVC introduce una serie de puntos de extensión en los que es posible inyectar código personalizado que modifique el comportamiento predeterminado. Estos puntos de extensión se encuentran por ejemplo en la lógica de enrutamiento, en la creación de los controladores, en la ejecución de las acciones del controlador, en la selección de las vistas o los “view engines”, etc.

5 – Modelo de programación que promueve una mejor arquitectura de las aplicaciones.

Las características inherentes del modelo de programación ASP.NET MVC promueven una mejor arquitectura de las aplicaciones, con una separación más clara entre la lógica de presentación, la lógica de negocio y la lógica de acceso a datos. Esta separación lógica también contribuye desarrollar un código más reutilizable debido al mayor desacoplamiento entre los distintos componentes.