DNM+ Online
dotnetmania 2.0
Introducción a ASP.NET MVC
ASP.NET MVC es un framework que hace posible el uso del patrón MVC (Modelo–Vista–Controlador) en aplicaciones ASP.NET. No es, por tanto, una nueva tecnología, aunque sí cambia radicalmente la forma de pensar y desarrollar aplicaciones Web usando ASP.NET. El presente artículo asume que el lector tiene conocimientos en el desarrollo de aplicaciones Web usando ASP.NET y se centra en explicar el patrón MVC y cómo lo podemos aplicar usando ASP.NET MVC.

Modelo vista controlador Modelo-Vista-Controlador es un patrón arquitectónico centrado en la capa de presentación que se apoya en tres conceptos fundamentales: •    Modelo: contiene los datos de la aplicación y la lógica de negocio asociada a ellos. •    Vista: muestra los datos del modelo, pero no contiene ninguna lógica de negocio (aunque puede contener lógica de presentación). •    Controlador: coordina la comunicación entre el modelo y la vista y decide qué tipo de vista debe presentarse al usuario en cada caso. El controlador es quien responde a las peticiones Web.

La clave del patrón MVC estriba en que separa la lógica de presentación de la lógica de negocio (en el patrón "clásico" de formularios Web de ASP.NET, el formulario Web se encarga tanto de la presentación como de la lógica de negocio). Esta separación ofrece grandes ventajas en cuanto a reutilización y pruebas. El desarrollo de tests unitarios, por ejemplo, se hace mucho más sencillo. No es que con los formularios Web no se pueda reutilizar código ni tampoco implementar tests unitarios, pero ello no es tan sencillo, y sobretodo natural, como ocurre en el caso de MVC. Para más información sobre el patrón MVC, recomendamos la lectura de [1]. Otra gran ventaja que ofrece ASP.NET MVC es la fácil e innata capacidad para enrutar URL determinadas al controlador que se desee. En una aplicación ASP.NET tradicional, la URL http://servidor/accounts/view.aspx?id=10 es enrutada al formulario view.aspx que se encuentre en el directorio /accounts de la aplicación Web, y se le pasa un parámetro id con valor 101. En una aplicación ASP.NET MVC son siempre los controladores quienes se encargan de procesar las peticiones Web, y existe un mecanismo (la tabla de enrutamiento) que determina qué controlador procesa cada petición que se reciba, según su URL. Esto nos permite usar fácilmente URL del tipo http://servidor/accounts/view/10, y dejar que la tabla de enrutamiento pase esta petición al controlador que sea necesario. El uso de estas URL semánticas tiene mucha importancia en aspectos como SEO (para más información, consulte [2]) o en la creación de aplicaciones RESTful2. Fundamentos de ASP.NET MVC Crear una aplicación Web usando ASP.NET MVC implica básicamente cuatro pasos fundamentales:

  1. Definir la tabla de enrutamiento que va a usar la aplicación, y que determinará qué controlador responde a cada petición Web.
  2. Crear los controladores necesarios
  3. Crear las vistas necesarias
  4. Crear el modelo

    A cada uno de estos apartados vamos a dedicarle una breve explicación. Preparación del entorno Antes de lanzarnos a crear aplicaciones ASP.NET MVC como locos, debemos configurar el entorno de desarrollo. Lo primordial es descargar ASP.NET MVC 1.0 desde http://www.microsoft.com/downloads/details.aspx?FamilyID=53289097-73ce-43bf-b6a6-35e00103cb4b&displaylang=en e instalarlo en nuestro ordenador (requiere VS2008 SP1). Una vez descargado e instalado ASP.NET MVC, nos aparecerá en Visual Studio una nueva plantilla de proyecto ("ASP.NET MVC Web Application") que es la que debemos escoger. Esta plantilla nos crea una aplicación con la infraestructura básica montada y opcionalmente un proyecto de tests unitarios asociado. La aplicación inicial que se crea contiene dos controladores ya creados, uno de los cuales (Account) interacciona con el Membership Provider de ASP.NET para permitir el acceso (login) de usuarios, así como el registro de nuevos usuarios. Este artículo asume que el lector crea la aplicación de demostración, y todas las variaciones se realizan sobre dicha aplicación. La figura 1 muestra la estructura básica de un proyecto ASP.NET MVC (la que crea por defecto la plantilla). El runtime de ASP.NET MVC por defecto espera que los controladores estén dentro de la carpeta Controllers y que las vistas estén dentro de la carpeta Views.El resto de carpetas creadas son para mayor comodidad: Content para incluir archivos estáticos de tipo hojas de estilo, Models para contener las clases del modelo y Scripts para incluir archivos de JavaScript.
    La tabla de enrutamiento Como ya se ha comentado, la tabla de enrutamiento es la responsable de decidir qué controlador gestiona cada petición Web basándose en la URL de dicha petición. En ASP.NET MVC, los controladores exponen acciones (en la práctica, métodos públicos de dicho controlador) y cada acción puede recibir parámetros. Dada una URL, la tabla de enrutamiento decide qué acción de qué controlador responderá a dicha petición Web y qué parámetros serán pasados a la acción. De esta forma, una tabla de enrutamiento puede definir que la URL http://host/clientes/ver/10 llame a la acción Ver del controlador ClientController con un parámetro entero con valor

    1. La tabla de enrutamiento se define en global.asax. Cuando creamos un nuevo proyecto ASP.NET MVC, se añade por defecto a global.asax el código que se muestra en el listado 1. Este código configura la tabla de enrutamiento para que:
  5. Ignore todas las peticiones cuya URL tenga la extensión .axd, dejando que sea el motor "estándar" de ASP.NET quien procese dichas peticiones. Así, una URL del tipo http://host/trace.axd no será procesada por el motor de ASP.NET MVC, sino por el motor "estándar" de ASP.NET.

  6. Enrute todas las peticiones cuya URL tenga la forma /controller/ action/id a la acción action del controlador controller, pasándole el parámetro id. Además, la tabla de enrutamiento establece los valores por defecto del controlador, de la acción y del parámetro id en caso que no sean suministrados.

    La tabla 1 muestra distintos ejemplos de enrutamiento según esta tabla de enrutamiento. Se pueden añadir a la tabla de enrutamiento varias entradas que se irán evaluando una tras otra, tal y como se muestra en el listado

    1. Este listado define una tabla de enrutamiento con dos entradas: una llamada LoginEntry, que tratará la URL http://host/Login, y otra llamada Default, que tratará las demás URL. Las entradas se evalúan en el orden en que son definidas, y si la URL suministrada no se puede enrutar mediante ninguna de las entradas se devolverá un error 404. De esta forma, en este caso la URL http://host/Login se enrutará (mediante la primera entrada) a la acción LogOn del controlador Account. El resto de URL serán tratadas por la entrada Default. Los controladores Los controladores son la clave de la aplicación ASP.NET MVC. Hemos visto cómo, a través de la tabla de enrutamiento, una URL se termina traduciendo a una acción de un controlador. A nivel de código, los controladores son clases de .NET que derivan de System.Web.Mvc.Controller y las acciones son básicamente métodos públicos de los controladores. El nombre del controlador es el nombre de la clase sin el sufijo Controller (todas las clases controlador deben terminar con este sufijo) y el nombre de la acción es el nombre del método. Así, la clase HomeController será la que implemente el controlador Home. A grandes rasgos, podemos asumir que cuando el usuario introduzca una URL en el navegador, eso se traducirá en la ejecución de una acción (método público) de un controlador, al cual se le pasan determinados parámetros. La acción es la responsable de decidir cómo debe procesarse dicha petición: interactuar con el modelo y generalmente seleccionar una vista y mostrarla (aunque podría hacer otras cosas, como permitir la descarga de un archivo). Para ello, todas las acciones deben devolver un resultado. Este resultado es un objeto de una clase derivada de ActionResult y es lo que indica al framework de ASP.NET MVC qué debe hacer. El listado 3 muestra cómo podría ser una implementación básica de un controlador (Home) que define dos acciones: una llamada Index, y otra llamada About3. La implementación de ambas acciones es muy simple, pero vamos a centrarnos en la implementación de la acción Index: en primer lugar se rellena el objeto ViewData, que es un diccionario (cuyas claves son cadenas y los valores de tipo object) que permite pasar información del controlador a la vista. Luego se llama al método View (definido en la clase base Controller). El método View lo que hace es crear un objeto ViewResult (que deriva de ActionResult) con la información necesaria para que el framework de ASP.NET MVC cargue la vista asociada a dicha acción. ¿Y cuál es la vista asociada a una acción? Pues por defecto es una vista que se llama igual que la acción y que se encuentra dentro de la carpeta Views/<Controlador>. Es decir, en nuestro caso la vista será Views/Home/Index.aspx. Existe una sobrecarga del método View que espera un nombre de vista y en este caso cargará la vista que se le indique. De esta manera, View("vista") cargará la vista Views/Home/vista.aspx. Existe una subcarpeta de Views específica llamada Shared: si el motor de ASP.NET MVC no encuentra la vista dentro de la subcarpeta del controlador, la buscará en Shared. Esto permite reutilizar una vista en todos los controladores (caso típico de una vista de error). La figura 2 muestra una estructura típica de vistas de un proyecto ASP.NET MVC: dentro de la carpeta Views una subcarpeta para cada controlador con sus vistas, y la carpeta Shared con las vistas compartidas. Además del método View, la clase Controller define otros métodos para devolver resultados de otros tipos; por ejemplo, el método JsonResult nos permite devolver un objeto codificado en formato JSON, y RedirectToAction nos permite redirigir la petición a otra acción (del mismo controlador o de otro). El espacio asignado a este artículo no nos permite entrar en detalles sobre estos métodos4.

    Creación de las vistas Una vista en ASP.NET MVC suele ser algo muy simple: debe pensar que no deben tener lógica de negocio, así que en la mayoría de casos se trata de HTML más un poco de código de servidor para controlar aspectos de lógica de presentación. Las vistas en ASP.NET MVC son archivos .aspx normales, aunque no suelen tener code-behind. Esto tiene su lógica, puesto que el código trasero de los formularios Web se utilizaba básicamente para implementar lógica de negocio. De todos modos, que no suelan tener code-behind no significa que no puedan tenerlo, y de hecho ello a veces es perfectamente lícito, pero antes de crear un archivo de code-behind para su vista, medite si no está realmente metiendo lógica de negocio en él5. Si es el caso, mueva esta lógica al modelo. Crear una vista se puede hacer directamente desde el Explorador de soluciones de Visual Studio 2008 utilizando la opción "Add" | "View" (tal y como se muestra en la figura 3). Esta opción despliega el cuadro de diálogo de "nueva vista", que se muestra en la figura 4. En este cuadro de diálogo, además del nombre de la vista debemos elegir: • Si la vista es una vista total o parcial. Las vistas parciales se implementan usando controles Web (.ascx) y permiten modificar solo una parte de la página Web. Se utilizan para reutilizar código (por ejemplo, un formulario de login que se use en varios sitios de la aplicación) y tienen especial importancia cuando usamos AJAX. • Si queremos que la vista sea tipada o no. Una vista tipada trabaja con un modelo que es una instancia de una clase determinada. Una vista no tipada trabaja con un modelo que es un object. • Si vamos a usar una página maestra, y en tal caso, cuál.

    Vamos a crear una vista vinculada al controlador Home, llamada Prueba. Para ello, haga clic con el botón derecho sobre la subcarpeta Home de la carpeta Views en el Explorador de soluciones y seleccione "Add" |"View"; use los datos mostrados en la figura 4. El sistema nos creará la vista Prueba.aspx, y podemos modificarla para que tenga un aspecto parecido al del listado 4.

    Ahora debemos modificar el controlador Home para que nos muestre la vista Prueba. Para ello, creamos una nueva acción llamada Prueba en el controlador, tal y como muestra el listado 5. Ahora la URL http://host/Home/Prueba nos mostrará la nueva vista.
    Veamos ahora rápidamente cómo tratar con los parámetros de una acción. Según nuestra tabla de enrutamiento, la URL http://host/Home/Prueba/100 nos tiene que invocar la acción Prueba con el parámetro id igual a 100. Si el lector usa esta URL, verá que efectivamente se muestra la vista; ahora sólo nos queda acceder a dicho valor. ¿Y esto cómo se hace? Pues muy sencillo: definiendo en el método de la acción un parámetro que se llame id, tal y como se hace en el código del listado 6. Si ahora prueba la URL http://host/ Home/Prueba/100, verá cómo la vista presenta el id recibido… De hecho, ahora el problema lo tenemos con la URL http://host/Home/Prueba: nos lanzará una excepción (The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Prueba(Int32)' in 'MvcApplication1.Controllers.HomeController'. To make a parameter optional its type should be either a reference type or a nullable type). ¿Cuál es el problema? Pues que nuestra tabla de enrutamiento indica que si el parámetro id no aparece, su valor será "". ASP.NET MVC intenta llamar al método Prueba con ese valor para id, pero no puede (porque la cadena vacía no es convertible a int). Tenga en cuenta que los métodos que definen acciones no pueden sobrecargarse, así que no podemos definir otro método Prueba sin parámetros. Entonces, ¿cómo podemos solucionar el problema? Pues hay varias maneras; una sería modificar la acción para usar Nullable<int> en lugar de int, tal y como se muestra en el listado 7.

    Otra posible vía sería modificar la tabla de enrutamiento para que el valor por defecto de id fuese un valor entero, por ejemplo

    1. El modelo El modelo no es otra cosa que el conjunto de clases que contiene los datos y la lógica de negocio asociada. Generalmente, un controlador en una acción interactúa con el modelo, y termina llamando a una vista (pasándole el modelo). La vista consulta el modelo y muestra los resultados. No vamos a entrar en este artículo en la creación de modelos complejos, aunque el lector interesado puede consultar [3], donde Brad Abrams muestra cómo crear un modelo utilizando Entity Framework. Para ver un ejemplo sencillo de cómo encaja el modelo en ASP.NET MVC, vamos a crear un modelo que simplemente sea una lista de clientes. Para ello, añadimos en la carpeta Modules dos clases con el código de los listados 8 y 9. Ahora modificamos el código de la vista Prueba.aspx que hicimos antes para que interaccione con el modelo. Primero, cambiamos el atributo Inherits de la directiva Page para que la clase derive de System.Web.Mvc.ViewPage<MvcApplication1.Models.Videojuegos>. Esto convierte a la vista en una vista tipada que trabaja con un modelo de tipo Videojuegos. Ahora podemos editar el código para mostrar los elementos del modelo en una tabla. Para acceder al modelo desde una vista, podemos utilizar la propiedad Model. Dicha propiedad es de tipo object para las vistas no tipadas, y del tipo correspondiente en el caso de las vistas tipadas. El código final se muestra en el listado 10. Finalmente, solo debemos modificar la acción Prueba del controlador Home para que cree una instancia del modelo y lo pase a la vista. Para pasar el modelo a la vista tenemos dos opciones: asignar la propiedad Model de la propiedad ViewData del controlador, o bien pasar el modelo a la llamada a View. En el listado 11 se muestra la primera de las opciones. Ahora, si navegamos a la URL http://host/Home/Prueba veremos cómo la vista nos muestra una tabla con los datos del modelo. Con esto termina este artículo de introducción a ASP.NET MVC. Aunque indudablemente nos han quedado muchos aspectos en el tintero, esperamos que al lector le hayan quedado claras las ideas básicas de ASP.NET MVC y le haya entrado el gusanillo de probar el nuevo framework, que realmente… ¡vale la pena!
blog comments powered by Disqus
autor
referencias