Hoy hemos publicado una beta ASP.NET MVC. Aquí podéis descargarlo. En www.asp.net/mvc tenéis tutoriales, quickstarts y vídeos.
Esta beta de MVC ASP.NET funciona tanto en .NET3.5 como en .NET 3.5 SP1 y tanto en VS 2008 como en Visual Web Developer 2008 Express SP1 (que es libre – y ahora soporta proyectos de librería y de aplicación web).
Esta beta de MVC ASP.NET incluye una licencia “Go-Live” que permite usarlo en entornos de producción. Las anteriores previews también permitían las implementaciones de go-live, pero no garantizaban nada en entornos de producción (lo que era una fuente de confusiones). La release de hoy es más claro en este aspecto.
Esta release se acerca más a una primera versión “V1” oficial, aunque todavía existen algunas características más que se agregarán antes de liberar la V1 final (incluyendo varias mejoras para VS). El equipo decidió llamar a esta versión “beta”, ya que la calidad y los resultados de las pruebas son mejores que las previews anteriores (se han corregido muchos errores y se ha mejorado el rendimiento), y sienten que las principales funciones del núcleo ya han sido “horneados suficientemente” y no esperan cambios en la release final del producto.
Este post contiene un breve resumen de algunas de las nuevas características y cambios que hay en esta compilación en comparación con la preview 5:
- Nuevo menú “Add View” en Visual Studio
- Nuevo directorio de Scripts y soporte para jQuery.
- Soporte integrado de Model Binder para tipos complejos
- Infraestructura de Model Binder refactorizado .
- UpdateModel fuertemente tipado y filtrado WhiteList de TryUpdate Model.
- Mejoras en los test unitarios en escenarios con UpdateModel y TryUpdateModel .
- Atributo fuertemente tipado [AcceptVerbs] .
- Mejores mensajes de errores de validación .
- Limpieza del HTML Helper y del refactorizado.
- Integracion de proyectos Silverlight/ASP.NET MVC.
- ASP.NET MVC Futures.
- Despliegue de Bin y del GAC.
También tengo previsto publicar algunos tutoriales completos en las próximas semanas explicando los conceptos de MVC ASP.NET en mayor profundidad para los que no lo hayan visto antes, y que buscan tutoriales sobre cómo comenzar.
Nuevo menú “Add View” en Visual Studio
En versiones anteriores de ASP.NET MVC teníamos que agregar manualmente vistas a través del cuadro de diálogo Project->Add New Item en VS , crear y cablear todo lo necesario manualmente (asegurándonos de uqe la estructura de directorios y archivos era correcta, ir al archivo de código trasero para especificar el modelo de ViewData fuertemente tipado, etc).
La beta de hoy hace que estos pasos sean mucho más sencillo. Ahora con solo poner el cursor en el editor de código en un método de acción de un controlador, hacemos clic derecho y seleccionamos en el menú “Add iew” (también podemos usar los atajos de teclado Ctrl-m Ctrl-v para hacer esto sin separar las manos del teclado:
Aparecerá el diálogo “Add View” que nos permitirá especificar el nombre de la vista que queremos crear, su masterpage, y opcionalmente el tipo fuertemente tipado del ViewData:
Visual Studio predecirá el nombre de la vista basándose en el nombre del método de acción en el que esté el cursor (podemos sobreescribirlo si queremos). Por ejemplo, si el cursor está en un método de acción con nombre “Edit” cuando le damos a “add view” predecirá el nombre del textbox con “Edit” en lugar de “Browse”.
El tipo fuertemente tipado del View data para una vista puede seleccionarse desde un ComboBox que lista todas las clases (o las referenciadas) del proyecto MVC:
Podemos seleccionar un tipo de la lista, o escribir una en el ComboBox. También podemos seleccionar un tipo inicial de la lista y ajustarlo. Por ejemplo, podemos seeccionar la clase “Product” de la lista y usar el soporte de edición del ComboBox para mapearlo como un IEnumerable<Product> – indicando una secuencia de productos:
Cuando hagamos clic en el botón “Add”, Visual Studio creará automáticamente la estructura de directorios apropiada, y añadirá una vista fuertemente tipada con el nombre adecuado y la clase base a nuestro proyecto. Por ejemplo, i seguimos los pasos anteriores para crear el directorio ViewsProducts (ya que mi clase controladora se llama “ProductsController”) y añadimos la vista fuertemente tipada “Browse.aspx” (que hereda de ViewPage<IEnumerable<Product>> – Ya que ese es el tipo de modelo que le indicamos en el diálogo anterior):
La vista creada se abrirá automáticamente en el IDE. Podemos implementar la vista con el intellisense completo (truco: aseguraos de hacer un build inmediatamente después de crear la vista para aseguranos de que el intellisense se ajusta al modelo fuertemente tipado:
Y en tiempo de ejecución tendremos una página de navegación de productos con ASP.NET MVC:
Nota: el archivo de la vista que hemos creado con esta beta está vacío. Para la versión final esperamos añadir algunas características que permitirá especificar en el cuadro de diáologo Add-view que queremos una vista/detalle en HTML o un formulario de edición/inserción basándose en el modelo fuertemente tipado que le digamos (y ya podremos partir de este html inicial y ajustarlo como queramos). En el futuro también integraremos ASP.NET Dynamic Data con MVC para que permita más posibilidades.
Nuevo directorio de Scripts y jQuery de apoyo
La plantilla de proyecto que se publica en esta release añade un nuevo directorio Scripts en nuestro proyecto. Este es el directorio recomendado para guardar los archivos de JavaScripts de nuestra aplicación.
Esta Beta añade tanto las librerías de ASP.NET AJAX y jQuery a este directorio
Los archivos jQuery son las librerías estándar de jQuery, y están licenciadas bajo la licencia MIT (Leed el post jQuery y Microsoft para más detalles.
Con las actualizaciones del SP1 de VS 2008 y Visual Web Developer 2008 Express, tendremos el intelisense básico de javascript cuando usemos los archivos de jQuery. Publicaremos un archivo de anotaciones para el intellisense de jQuery en unas semanas que aporten un soporte más completo de jQuery (incluyendo la habilidad de tener intellisens usando varios comandos/selectores). ESto estará disponible en la próxima actualización de ASP.NET MVC.
Mejoras en Form Post y en Model Binder
Una de las áreas más grandes en las que hemos trabajado en la Preview 5 fué el tema relacionado con los escenarios de form post. Publiqué un post que trataba este tema en profundidad el mes pasado.
La veta de hoy incluye varias mejoras y refinamientos. Entre los que se incluyen:
- Soporte integrado de Model Binder para tipos complejos
En la preview 5 se introdujo el concepto de “model binders” – que nos permitían mapear valores de entrada de una petición post a tipos complejos de .NET que se pasaban a métodos de acción como parámetros. Los models binder de la preview 5 eran extensibles, y podíamos crearnos nuestros binders personalizados y registrarlos en varios niveles del sistema. La preview 5 no incorporaba ningún binder de fábrica. En la beta de hoy se incluyen binders, pre-registrados, que podemos usar para administrar los tipos básicos de .NET – sin tener que escribir código ni registrarlos.
Por ejemplo, podemos crear la siguiente clase persona con propiedades estándar:
Y tener un método de acción de un controlador que tome como parametros este tipo con el código siguiente:
Como el parámetro se llama “person”, el model binder buscará valores cuyos nombres estén en el formato “person.Name”, “person.Age”, “person.Email”. Usará esos valores para crear un nuevo objeto “Person” que se pasará a nuestro método de acción.
Los programadores podrán sobreescribir la lógica de mapeado de nombres con el atributo [Bind[ que hemos introducido en la beta de hoy – y estableciendo la propiedad “Prefix”. Por ejemplo, si establecemos la propiedad prefix a “PersonToSave”, el binder buscará los valores: “PersonToSave.Name”, “PersonToSave.Age”, y “PersonToSave.Email” cuando crea una instancia del tipo person. Podemos establecer esta propiedad como un string vacío para tener un mapeo del tipo “Name”, “Age” e “Email” sin prefijo:
El atributo [Bind] nos permite especificar la propiedad “Included” o “Excluded” – que puede ser usada como una “lista blanca” o “lista negra” para que no sean mapeadas en los objetos. Por ejemplo, el código siguiente indica que sólo queremos mapear las propiedades “Name” y “Age” en nuestro objeto person:
Nota importante de seguridad: En general no querremos que se mapeen propiedades que no queremos mapear. Tendremos que usar siempre este include/exclude cada vez que queramos propiedades que no se mapeen a objetos. Por ejemplo: suponiendo que hay una propiedad “Salary” en los objetos “Person” – podríamos no querer mapear esta propiedad a menos que queramos que el usuario le de algún valor. Tenemos que ser explícitos sobre las propiedades que no queramos mapear para prevenirnos de que algún hacker intente hacer una petición post perniciosa e intente poner propiedades adicionales que no sean editables en la interfaz de usuario
- Infraestructura de Model Binder refactorizada
El sistema de model binder ha sido refactorizado significativamente para la versión beta. Podemos reusar la funcionalidad de una manera mucho más granular cuando creemos nuestros model binders personalizados.
Los model binders también se usan ahora en los métodos UpdateModel y TryUpdateMOdel – permitiéndoons escribir un binder y reusarlo en cualquier parte en la que se pasen valores a un formulario en ASP.NET MVC
- Mejora de los métodos UpdateModel y TryUpdateModel
Los métodos UpdateModel y TryUpdateModel ahora soportan nuevas opciones y sobrecargas (incluyendo mas opciones de listas blancas y listas negras).
Soportan opcionalmente sólo llamar a “UpdateMOdel” para crear una instancia con las reglas de binding por defecto (con la preview 5 teníamos que añadir siempre la lista blanca – y varias personas han pedido una opción para mapearlas todas):
Otra novedad en esta beta es la posibilidad de definir un filtro de lista blanca fuertemente tipada que usaremos con UpdateModel/TryUpdateModel. Podemos hacerlo definiendo una interfaz con el subconjunto de propiedades enlazables que queramos mapear. Por ejemplo, aquí estoy definiendo la interfaz “IPersonFromBindable” con sólo tres propiedades (y no tiene la propiedad salario):
Podríamos indicalre que queremos usar este contrato para limitar las propiedades que se van a mapear con el código siguiente:
De esta manera nos aseguramos que sólo esas propiedades que hay definidas en la interfaz IPersonFormBindable son mapeadas – y no la propiedad Salary.
Esto garantizará que se asignan sólo a esas propiedades definidas en la interfaz de IPersonFormBindable – y que no está asignado el salario de una.
- Mejoras en los test unitarios en escenarios con UpdateModel y TryUpdateModel
Con la preview 5 teníamos que usar objetos mock para hacer los test unitarios en escenarios de peticiones post en formularios que usaban los métodos UpdateModel o TryUpdateModel. La beta de hoy nos permite hacer test unitarios en estos escenarios sin tener que usar objetos mock
Hay una nueva interfaz IValueProvider que se ha introducido en la beta que usa la infraestructura de model binding para obtener los valores a enlazar (como oposición a hacerlo siempre contra la petición del objeto). La clase FormCollection (que está en la beta) implementa esta interfaz – y podemos pasar explícitamente una instancia a UpdateModel/TryUpdatemodel para enlazar los valores del formulario
Por ejemplo: en el método de acción “Save” estamos enlazando todos los valores del formulario a FormCollection(que será pasado como argumento al método de acción). Ahora puedo pasar esta colección de formularios a la llamada a UpdateModel y tener los valores mapeados en el modelo de objetos person que estamos usando como parametros:
Ahora podemos crear test unitarios en estos escenarios usando el siguiente código (fijáos en que no necesitamos ningún tipo de objeto mock – sino que sólo creamos una colección formcollection, la calculamos, y la pasamos como parámetro):
Ahora creamos un test que falle (debido a entradas inválidas para la propiedad Age) usando el código siguiente. Fijaos que cómo estamos comprobando que se está mostrando el formulario de edición (para que el usuario pueda corregir el problema) en un escenario de error en un formulario:
No tenemos que crear ningún objeto mock para los test unitarios en estos escenarios
- Atributo fuertemente tipado [AcceptVerbs]
La preview 5 introdujo el atributo [AcceptVerbs] para indicr los diferentes verbos HTTP que soporta un método de acción.
En la preview 5 siempre especificábamos estos verbos con strings. Seguimos soportando esto en esta beta, pero también hemos añadido una enumeración fuertemente tipada para esta tarea. Por ejemplo:
La veta de hoy no requiere que le especifiquemos el [AcceptVerbs] en ambos métodos de acción. Por defecto, ASP.NET MVC busca un método de acción que soporta el verbo de la petición HTTP actual – y si no lo encuentra usará el método que no tenga este verbo explícitamente indicado. Esto salva algunos escenarios comunes en escenarios GET/POST (no necesitaremos decorar los métodos GET).
- Mejores mensajes de errores de validación
Una de las características que no metimos al final en la beta (pero que será añadida en la próxima actualización) es el soporte para que podamos mostrar errores de validación personalizados desde nuestro modelo de clases (como oposición a personalizarlso en los controladores como hasta ahora). EStamos investigando unas cuantas formas de hacer esto – incluyendo el añadir soporte para la interfaz IDataErrorInfo, y el soporte para los nuevos atributos de Dynamic Data en el namespace System.ComponentModel.DataAnnotations.
Una mejora que no hicimos en la beta de hoy es hacer los mensajes de validación más amigables (esperamos eliminar la necesidad de crear mensajes personalizados para la mayoría de los casos):
Limpieza de la ayuda HTML
La beta de hoy tiene algunas mejoras en los HTML helpers (en generarl es un área de trucos – ya que hay muchas combinaciones de sobrecargas que podemos hacer).
- Html.Form-> Html.BeginForm
Uno de los cambios e usabilidad que hemos hecho en esta beta es renombra el Html.Form() a Html.BeginForm() y soportamos dos formas e usarlo – uno aprovechando el uso de un using, y el otro aprovechando el método Html.EndForm(). La razón por la que hemos movido estas dos aproximaciones es que hemos visto un montón de preguntas y confusiones en los foros sobre cómo funciona la sentencia using en este escenario (el patrón es poco familiar para muchos desarrolladores).
Aquí tenéis dos ejemplos que muestran cómo podemos implementar lo anterior (completado con mensajes de error) usando las dos formas:
Enfoque 1: uso de estado con el Html.BeginForm():
Este enfoque usa el patron IDisposable con la palabra using en VB y C# para terminar el </form>:
Enfoque 2: Html.BeginForm() explícito y Html.EndForm():
Esta aproximación usa la llamada a EndForm() pra cerrar el </form>:
Los desarrolladores pueden usar la que más les guste – ambas aproximaciones hacen exactamente lo mismo.
Se han movido mucho HTML Helper Methods para que sean métodos de extensión
Uno de los cambios que hemos hecho en esta beta es mover muchos de los HTML helper methods a métodos de extensión bajo el namespace System.Web.Mvc.Html (anteriormente eran instancias de métodos de la clase HtmlHelper class). Hemos hecho algo similar con los helper methods de AJAX en la Preview 5 (ahora están en System.Web.Mvc.Ajax).
Estos cambios no afectan al intellisense en la vista de markup (por defecto referenciamos el namespace en el archivo web.config para que funcione como antes – sin embargo si estáis migrand ouna aplicación desde la preview 5 no tendréis que añadir el namespace al web.config, leed las notas de la release sobre cómo hacer esto). Si tenéis clases/test que usan helper methods aseguraos de añadir el using necesario.
La razón de este movimiento ha sido para permitir a los desarrolladores una mayor flexibilidad para añadir/eliminar/reemplazar nuestras implementaciones internas (así como darnos a nosotros mismos mayor flexibilidad en el futor). Si queréis sobreescribir el método HTML de renderizado para un método podemos hacerlo fácilmente – manteniendo así el mismo nombre/firma en nuestro markup.
Integracion de proyectos Silverlight/ASP.NET MVC
Cuando creamos un proyecto Silverlight 2 con Visual Studio Visual Web Developer 2008 Express (usando el recientemente publicado 2 Silverlight y de la VS 2008 herramientas para la descarga de Silverlight ), ahora tenemos la posibilidad de seleccionar un proyecto ASP.NET Web Site, ASP.NET Web Application Project y ahora un ASP.NET MVC Project:
Cuando elegimos esta opción, Visual Studio copiara y desplegara/actualizará la aplicación Silverlight en la aplicación ASP.NET MVC cuando hagamos un cambio y hagamos un build en el IDE. Conseguimos así poder integrar fácilmente una aplicación Silverlight como front-end (ejecutandose dentro del navegador) con ASP.NET MVC como web back-end – abriendo nuevas posibilidades bastante interesantes.
ASP.NET MVC Futures
En las últimas release de ASP.NET MVC, las diferentes caracteristicas se han dividido en dos assemblies – System.Web.mvc.dll y Microsoft.Web.mvc.dll. El último ensamblado + espacio de nombres contiene características de “Futures” que aún no habían sido publicadas para entregar con la V1 del producto. Ha medida que estas características se terminan las movemos al assembly principal – y también cambiamos el namespace (de Microsoft.Web.mvc a System.Web.mvc).
Las versiones anteriores se publicaban y añadían un assembly “futures” cuando hacíamos un File-> New ASP.NET MVC Project. Con la beta de hoy no vamos ha añadir este assemblie – tenéis que añadirlo a vuestros proyectos explícitamente si queréis usarlo. La razón de esto es que los desarrolladores puedan distinguir esas características que estarán soportadas en la V1 del producto (lo que implica el soporte del producto para mejorar la compatibilidad), y aquellas que sigan evolucionando en el futuro (y no se añadiran al producto soportado hasta la siguiente versión).
Importante: El ensamblado de futures (viene con todo el código fuerte) continuará entregándose y funcionara con ASP.NET MVC V1. Así que si hay una característica que queráis, no tendréis que preocuparos ya que será transparente para vosotros (sigue ahí y podéis seguir usándola). Sólo tenéis que rerferenciar el assembli y usarlo en vuestro proyecto.
Vamos a enviar una versión del ensamblado ASP.NET MVC Futures que funciona con la beta más tarde. Podréis descargarla de aquí.
Despliegue de Bin y del GAC.
Esta beta soporta tanto el despliegue en el GAC (en el que instalais el assembly una vez para la máquina) así como el despliegue en el directorio bin (donde guardamos una copia del assemblie en el directorio de la aplicación).
Usaremos el GAC para permitir las actualizaciones automáticas de los servicios via Windows Update (en el que un administrador pueda parchear automáticamente la máquina – como se hace con el resto del framework de .NET hoy, sin tener que ir actualizando cada aplicación individualmente). Una desventaja del despliegue en el GAC es que puede hacer que el despliegue de esas apliaciones sea más duro – ya que normalemente no tenemos acceso de admin en la máquina servidor (y necesitamos permisos de administración para instalar componentes en el GAC).
Para asegurarnos de que estos escenarios funcionan bien (y para asegurarnos de que no necesitamos que nuestro host instale nada más que ASP.NET 3.5 para que ASP.NET MVC funcione) también soportamos la opción desplegar los asemblies de ASP.NET MVC en el directorio bin de nuestra aplicacion. Esto nos permitira copiar la apliación en el servidor y que funciones (sin que el administrador instale nada). Lo malo de esta opción es que serás responsalbe de mantener acutalizados los asemblies cada vez que salga una nueva version – Windows Update no puede buscar todos los directorios de una máquina por ti.
Resumen
La beta de hoy está un paso más cerca de ASP.NET MVC 1.0. Mientras que no estén el 100% de las opciones terminadas, pensamos que todos los subsistemas están muy cerca de estar completamente acabados.
Voy a intentar postear algunos tutoriales en las próximas semanas en el que mostraré cómo usar ASP.NET MVC desde el principio, e ir alcanzado poco a poco escenarios más ricos. En la lista de tutoriales está incluido mi poco famoso AJAX con MVC que sigo prometiendo que escribiré (mi excusa: Silverlight 2, ASP.NET MVC, .NET 4.0, VS 10, y Windows 7 siguen ciclos que están ocurriendo en mi equipo – y desafortunadamente he estado realmente ocupado).
Como siempre he venido diciendo, lo repito: Si no te gusta el modelo MVC o no encuentras natural esta forma de desarrollar, no tienes que usarlo. Es una oferta especial – y no va a reemplazar a ningún modelo de WebForms. Tanto los WebForms como MVC serán soportado y ampliados (ASP.NET WebForms en .net 4.0 añadirá características de rutado URL mucho más rico, mejor soporte para CSS, control completo sobre la propiedad ClientId, más características aJAx, y más sobre lo que escribiré pronto). Así que si no te gusta la opción del MVC, no te preocupes, no sientas que necesitas usarlo (no lo necesitas).
Espero que sirva.
Scott.
Traducido por: Juan María Laó Ramos.