Simone Chiaretta, desarrollador, MVP, bloguero y autor de un libro sobre ASP.NET MVC Framework, entre otros méritos, recoge en su recomendable bitácora Code Climber unas cuantas buenas prácticas a considerar cuando trabajamos en proyectos ASP.NET MVC, que cito y comento a continuación:
- Borra el AccountController. Siendo fieles al principio YAGNI, prácticamente lo primero que deberíamos hacer al crear un proyecto ASP.NET MVC es eliminar todo lo relativo al sistema de cuentas de usuario incluido por defecto en el mismo, que muy difícilmente nos será útil tal cual en proyectos reales.
- Aísla los controladores del mundo exterior, no dejes que dependan de elementos externos como
HttpContext
, datos del reloj (hora/fecha actual), ni accedas directamente a bases de datos o elementos de configuración. Harán tu aplicación muy poco flexible y difícil de testear. - Utiliza un contenedor IoC, te ayudará a gestionar las dependencias de los controladores, facilitando la sustitución de estos elementos de forma muy sencilla, sobre todo, vistas a la realización de pruebas.
- No utilices cadenas mágicas, dificultan la detección de errores. No es buena idea usar expresiones del tipo
ViewData["variable"]
, las vistas tipadas son el mecanismo ideal para pasar información desde el controlador. También es peligroso el uso de los helpers que utilizan cadenas para referirse a nombres de controladores y acciones, y para ello existen alternativas basadas en expresiones lambda o plantillas T4 bastante potentes. - Crea tus propias convenciones tomando como base las propuestas por el framework MVC. Por ejemplo, crea controladores y vistas base de las que heredar, e implementa en ellos aspectos comunes.
- Presta atención a los Verbos, a los verbos HTTP, claro ;-). Envía información desde formularios con el método POST y genera las vistas que muestran datos desde peticiones GET. Utiliza el patrón Post-Redirect-Get.
- DomainModel != ViewModel, el primero representa los datos y lógica del dominio, mientras que el segundo se diseña exclusivamente para satisfacer las necesidades de información de las vistas y normalmente serán estructuras planas, y principalmente strings, que es el tipo de datos que normalmente necesitan los controles de entrada y salida de datos.
- Usa ActionFilters para manejar los datos compartidos entre distintas acciones y controladores, dejando que éstos se centren en la tarea que deben realizar. Puedes utilizar filtros para cargar información común (por ejemplo, para componentes de una página maestra) y utilizar vistas parciales para mostrarla.
- No utilices el code-behind. Nunca. En mi opinión, el code-behind no es necesario (al menos no le he encontrado aún ninguna utilidad en MVC), y puede crear confusión si compartes tu código con otros desarrolladores que no esperarán encontrar nada ahí.
- Escribe HTML siempre que puedas. No utilices helpers que lo único que van a hacer es generar el código HTML por ti. Es decir, mejor usar
<input type="submit" value="grabar" />
que<%=Html.Submit("grabar") %>.
- Si hay un if, escribe un helper. Las vistas deben ser fáciles de leer, y muchos bloques de códigos mezclados con marcado no facilita la tarea. Dado que en las vistas la lógica ha de ser necesariamente muy simple, probablemente puedas crear helpers que simplifiquen la composición del marcado en casos en los que hay condiciones
if
o buclesfor
. - Elige el motor de vistas cuidadosamente, WebFormViewEngine no es el único ni, para Simone, el mejor de los existentes. De hecho, recomienda el uso de Spark, un motor de vistas libre en el que es el propio HTML el que controla el flujo de composición del interfaz de forma muy sencilla y potente:
<viewdata products="IEnumerable[[Product]]"/>
<ul if="products.Any()">
<li each="var p in products">${p.Name}</li>
</ul>
<else>
<p>No products available</p>
</else>
Opiniones aparte, la verdad es que es un interesante grupo de consejos a tener en cuenta.
Fuente: 12 ASP.NET MVC Best Practices
Publicado en: Variable not found.
Publicado por José M. Aguilar a las 12:12 a. m.
Etiquetas: asp.net, aspnetmvc, buenas prácticas, desarrollo
9 Comentarios:
Perdón por sembrar la semilla de la discordia. Vengo a poner entre signos de interrogación al "nunca" de la 9 ("No utilices el code-behind. Nunca").
Yo diría "medita en cada caso acerca de la necesidad del codebehind, minimizando su uso en lo posible y dentro de lo razonable".
Y antes de que se me vengan encima déjenme decirles que puedo justificar esa opinión sin ponerme colorado (y que no soy el único). Pégenle si no una mirada a El estilo, la legibilidad, los “malos” programadores y el ¿diabólico? codebehind en el Microsoft .Net MVC (perdón por el autobombo), donde condenso un poco la discusión que es -en serio- más que interesante.
¡Hola, Andrés! Encantado de que vengas a sembrar la semilla del debate (que no de la discordia) ;-D
Obviamente, el autor del artículo que cito (Simone) y yo mismo pertenecemos a la corriente filosófica del "para qué el code-behind". Partamos de ahí. :-)
Conozco el debate al que haces referencia y que bien citas en ese post de tu magnífico blog. Pero sin radicalismos, no creo que sea diabólico, ni que haga aparecer al mal programador que todos llevamos dentro ;-), ni que el hecho de usarlo vaya a provocar que introduzca ahí código más propio del controlador... Se puede crear un sistema perfectamente ajustado al patrón utilizando el code-behind, seguro. :-)
En mi caso, la cuestión es bastante simple: nunca lo he necesitado. Suelo ser bastante práctico y a priori no me cierro en banda a ninguna de las opciones, pero sí es verdad que hasta la fecha no he encontrado ningún motivo para utilizar el code-behind.
Bueno, miento ;-). De hecho, en las primeras previews del producto el code-behind se utilizaba exclusivamente para declarar las clases genéricas, puesto que la directiva inherits de las páginas no permitía utilizar notación C# o VB para la herencia y había que utilizar la notación estándar del CLR. Después, desapareció y nunca más lo he echado en falta.
Por otra parte, la idea de mezclar en una vista html, javascript, css y C# en el mismo fichero no me parece tan terrible. Los tres primeros debes tenerlos juntos cuando desarrollas para la web obligatoriamente, por lo que el problema se reduce a la unión de "lenguajes web" + C#. Hay que tener en cuenta que el C# que vamos a encontrarnos en una vista ha de ser obligatoriamente simple, en caso contrario puede ser una señal de que estamos haciendo algo mal: iteraciones, condiciones simples, llamadas a helpers... siempre y exclusivamente destinado a generar marcado y código de presentación. Existen, además, técnicas para simplificar el marcado, como el uso de helpers o vistas parciales que nos pueden ayudar cuando estemos trabajando en escenarios más complejos sin necesidad de recurrir al code-behind, un sitio en el siguiendo las convenciones propuestas por el framework, no se espera que haya nada.
Por eso cuando encontré ese "nunca" del punto 9 en el post de Chiaretta me sentí totalmente identificado pues, en mi caso, se trataba simplemente de la constatación de un hecho.
Un saludo, y gracias por compartir otro punto de vista en este tema tan interesante, Andrés!
Saludos.. Soy nuevo en eso.. Pero me llama la atención el no uso de codeBehind.. mi preguntra.. ¿que lo hace ser tan malo? Yo lo uso comunmente para maximizar la capacidad de reusabilidad de elementos y facilidad en el entendimiento del la estructura general de la aplicación. Ademas la idea de tener componentes como css, java script, separados no es nada malo. Te da mejor comprension y manejabilidad.
Gracias por el debate..
Hola, Rome. :-)
Como decía en mi comentario anterior, no es cuestión de ser bueno ni malo... simplemente en ASP.NET MVC nunca me ha hecho falta hasta el momento. Sólo eso.
La propia separación impuesta por el patrón Modelo-Vista-Controlador hace innecesaria la implementación de lógica en la capa de presentación más allá de la necesaria para preparar el interfaz, y por ello el codebehind deja de tener el sentido... o al menos, el sentido que tiene en webforms. Y como comentaba, no he encontrado en ASP.NET MVC ningún caso en el que tenga que utilizar codebehind para solucionar un problema concreto.
Lo mismo ocurre, pero al revés, al programar con Webforms: siempre he utilizado codebehind, pues es la práctica habitual y, como dices, te permite separar la lógica de control de la presentación. Nunca he encontrado un motivo para tener que prescindir de él, por lo que lo lógico es seguir usándolo.
Saludos y gracias por aportar!
Analizando sus comentarios, veo que esto de usar el codigo de la interfaz (al menos en la Web), es una cuestion de gustos, de hecho tienes razon amigo jose, cuando manifiestas que no hay limitantes en los desarrollos ha realizar y lo que siempre he escuchado es que es una cuestion de gustos (Opcional), solo que en tu articulo, al leerlo lo senti como algo fuera de orden mas que de gustos. Gracias por el debate aunque sencillo importante para aclarar.
Este comentario está retardado pero como soy principiante en desarrollo con MVC quiero preguntar en cuanto a la primera de las mejores prácticas. Si es necesario o buena practica borrar el accountcontroller,¿es mejor entonces crear nuestras propias tablas de usuarios y manejar por nuestra cuenta las credenciales de los usuarios y la seguridad?
Hola, Anónimo!
Bueno, el código del AccountController te puede ser de utilidad en proyectos muy simples. Si tus requisitos son básicos, sin hacer nada tendrás implementado un sistema de membresía completo.
En proyectos reales los requisitos suelen ser más fuertes, y la propuesta de la plantilla MVC (que utiliza de base ASP.NET) se queda corta o, simplemente, no coincide con las necesidades. En este caso es cuando debes eliminarlo, para no dejar código "muerto" en el proyecto. Esto, verás que es bastante habitual (¡incluso en ejemplos que cuelgo en el blog!), y no hace más que introducir ruido.
En fin, que no hay solución buena o mala; siempre depende del escenario en el que se utilice.
Saludos.
A que te refieres en el punto :: "Aísla los controladores del mundo exterior" :: con relacion a httpcontext? podrias ampliar mas el tema con un ejemplo, gracias!
Emiliano
Hola, Emiliano.
El punto, en general, hace referencia a que el uso de cualquier elemento externo en el controlador introduce una dependencia en esta capa, que la hace más difícil de testear.
Es decir, si por ejemplo en una acción usas Request["X"] para acceder a los datos de la petición en lugar de utilizar el binding, a la hora de testearlo te verás obligado a falsificar estos objetos e inyectarlos en tu clase.
Saludos.
Enviar un nuevo comentario