Está en la página 1de 27

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.

com

Manual del framework ASP.NET MVC


Manual dedicado al framework de ASP.NET MVC, basado en el patrn Modelo Vista Controlador, para el desarrollo de aplicaciones web con tecnolo!"as Microsoft.

Autores del manual


Este manual ha sido realizado por los siguientes colaboradores de DesarrolloWeb.com:
Eduard Toms

Technology Specialist en raona http://geeks.ms/blogs/etomas (8 cap tulos!

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com

Introduccin a ASP.NET MVC


ASP .NET MVC es el #nue$o% framework &ue 'a sacado Microsoft para desarrollar aplicaciones web, usando tecnolo!"a .NET. Lo de nuevo entre comillas, viene porque la primera versin sali, aproximadamente, a mediados del 2009 y ya sabemos que en este mundo, casi dos aos son una eternidad. De hecho, actualmente el frame or! ya va por su tercera versin y es esa tercera versin la que vamos a ver en esta serie de art"culos. #$%.&'( )*+ ,.0 permite el desarrollo de aplicaciones eb usando .&'( -rame or! ..0 y *isual $tudio 20/0. &o puede usarse *isual $tudio 2000 aunque s" la versin 'xpress 12ratuita3 de *isual 4eb Developer. #$%.&'( )*+ ,.0 no viene de serie, ni con *isual $tudio 20/0 ni con *isual 4eb Developer 20/0. %uede instalarse usando 4eb %latform 5nstaller o bien descar26ndolo desde http788 .microsoft.com8do nloads8en8details.aspx9-amily5D:d2920bc/;f.0c;.e9<;a0=.; 2a.<<a22c0f=>displaylan2:en

Sustituye ASP.NET MVC a ASP.NET?


'sta es una de las primeras pre2untas que se reali?a mucha 2ente cuando oye a hablar por primera ve? del -rame or!. La respuesta es un rotundo no, y por dos ra?ones principales7 /. #$%.&'( )*+ est6 construido usando #$%.&'(. (odos los aspectos transversales de #$%.&'( 1autenticacin, cache, sesin, roles,@3 si2uen siendo los mismos en #$%.&'( )*+. 2. $i a al2o puede sustituir #$%.&'( )*+ es a 4ebforms, es decir a las p62inas .aspx. %ero )icrosoft ya ha anunciado que esto no suceder67 ambos frame or!s 1#$%.&'( )*+ y 4ebforms3 se se2uir6n evolucionando. #s" pues si has invertido tiempo en conocer y dominar 4ebforms, estate tranquilo7 ese conocimiento si2ue siendo v6lido. De todos modos yo te animo a que eches un vista?o a #$%.&'( )*+ y lue2o decidas cu6l de los dos frame or!s te 2usta m6s para el desarrollo de aplicaciones eb usando .&'(.

El Patrn Modelo - Vista - Controlador MVC!


#$%.&'( )*+ es, b6sicamente, una implementacin del patrn )odelo ; *ista ; +ontrolador 1)*+3 para tecnolo2"a #$%.&'(. 'l patrn )*+ no es ni nuevo 1data de finales de los aos A03 ni est6 pensado para aplicaciones eb, pero en realidad en aplicaciones eb encaBa perfectamente. Crevemente podemos decir que el patrn )*+ separa la l2ica 1y acceso a datos3 de una aplicacin de su presentacin, usando , componentes7 /. )odelo7 Depresenta las re2las de ne2ocio de la aplicacin 1y el acceso a datos subyacente3. 2. *istas7 Depresentan la presentacin de la aplicacin. ,. +ontrolador7 #ctEan de intermediario entre el usuario y el )odelo y las *istas. Deco2en las peticiones del usuario, interaccionan con el modelo y deciden que vista es la que debe mostrar los datos. 'n el contexto de #$%.&'( )*+7 (oda la l2ica de ne2ocio y el acceso a datos es el )odelo 1en muchos casos el )odelo puede estar en uno o varios assemblies referenciados3. Las vistas contienen, b6sicamente, el cdi2o que se env"a al nave2ador, es decir el cdi2o F()L 1y cdi2o de servidor asociado, siempre y cuando este cdi2o ha2a cosas de presentacin, no de l2ica de ne2ocio3. Los controladores reciben las peticiones del nave2ador y en base a esas, deciden que vista debe enviarse de vuelta al nave2ador y con quG datos.

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com

Venta"as de ASP.NET MVC


La ventaBa que primero salta a la vista de #$%.&'( es la facilidad con la que se 2eneran HDL sem6nticas, es decir HDL que ten2an la forma http788servidor8ver8productos8cafeteras en lu2ar de http788servidor8productos8ver.aspx9code:cafeteras. Las HDLs sem6nticas se indexan meBor en los buscadores y son una pr6ctica $'I habitual. &o es que en ebforms no se puedan hacer, es que en #$%.&'( )*+ vienen de serie. Itras ventaBas, m6s a nivel tGcnico, son que con #$%.&'( )*+ se facilita mucho el probar nuestra aplicacin 1especialmente usando pruebas unitarias3 y que el uso correcto del patrn )*+ facilita la reutili?acin de cdi2o de manera mucho m6s efectiva que en ebforms. %or supuesto, todo esto tiene un precio7 la curva de aprendi?aBe de #$%.&'( )*+ puede ser m6s alta que la de ebforms, especialmente si nunca has desarrollado para eb. # diferencia de ebforms, que te abstrae de F((% y F()L, #$%.&'( )*+ est6 Jmucho m6s cerca de la ebJ, lo que hace necesario conocer F((%, F()L y Kavascript para trabaBar con Gl. De todos modos eso no deber"a echarte para atr6s7 si quieres crear aplicaciones eb es normal que debas conocer los protocolos y len2uaBes en los que se asenta la eb, Lno9 # lo lar2o de esa serie de art"culos, que vamos a publicar en el )anual de #$%.&'( )*+, iremos viendo cmo desarrollar una aplicacin #$%.&'( )*+, usando la versin ,.0 del frame or!.
Artculo por

Eduard Toms

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com

#a $rimera a$licacin ASP .NET MVC


Vamos a $er cmo paso a paso reali(ar el, )a t"pico, #*ola Mundo% usando ASP .NET MVC.

Creacin del $royecto


Hna ve? instalado #$%.&'( )*+ ,, nos aparece un nuevo tipo de proyecto en *isual $tudio7 #$%.&'( )*+ , #pplication7

Le damos el nombre que queramos 1en este caso )vcFello4orld3 y el directorio donde se va a 2enerar y listos. 'n el si2uiente paso nos pre2untar6 si queremos una aplicacin J'mtpyJ o J5nternet #pplicationJ, y seleccionamos J'mptyJ. La diferencia es que en el se2undo caso ya se nos 2enera un conBunto de controladores y vistas por defecto, y ahora este cdi2o nos liar"a m6s que ayudar"a as" que vamos a obviarlo. +on J'mptyJ empe?amos con una aplicacin #$%.&'( )*+ vac"a. 'l desple2able J*ie 'n2ineJ tiene dos valores7 Da?or y #$%M. 'sto hace referencia a la tecnolo2"a con la cual se implementan las vistas. $i seleccionamos #$%M nuestras vistas ser6n archivos .aspx, mientras que si usamos Da?or nuestras vistas ser6n archivos .cshtml 1o .vbhtml si usamos *isual Casic3. Da?or es una sintaxis nueva mucho m6s compacta que #$%M y es, por tanto, la que vamos a usar nosotros.

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com

-inalmente le damos a JI!J y eso nos va a crear nuestro proyecto vac"o.

Estructura de un $royecto ASP.NET MVC


5ncluso en una aplicacin vac"a, *isual $tudio nos habr6 creado varias carpetas, y al2unos archivos7

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com

#$%.&'( )*+ si2ue lo que se conoce como convention over confi2uration, es decir7 en lu2ar de usar archivos de confi2uracin para ciertas tareas, se usan convenciones predefinidas. N esas convenciones son re2las como las si2uientes7 /. Las vistas se ubican en la carpeta *ie 2. Los controladores son clases cuyo nombre termina en +ontroller Las carpetas que nos crea *isual $tudio por defecto son las si2uientes7 /. 2. ,. .. <. +ontent7 %ara tener contenido est6tico 1im62enes, hoBas de estilo, @3 +ontrollers7 %ara ubicar nuestros controladores )odels7 %ara ubicar las clases del modelo. $cripts7 %ara tener archivos con cdi2o Bavascript *ie s7 Donde van las vistas de la aplicacin

Creacin del controlador y de la accin


*amos a crear un controlador que se encar2ue de recibir la peticin del nave2ador 1y que devuelva la vista que di2a JFola )undoJ3. %ara ello clic! con el botn derecho sobre la carpeta J+ontrollersJ y seleccionar #dd O +ontroller. *isual $tudio nos pre2untar6 el nombre del controlador7

%odemos ver que por defecto el nombre termina con +ontroller. )odificamos para que en lu2ar de Default/+ontroller sea Fome+ontroller y le damos a #dd. 'so nos crear6 una clase Fome+ontroller en la carpeta +ontrollers con el cdi2o7
public class HomeController : Controller { //

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com


// GET: /Home/ public ActionResult Index() { return Vie ()! " "

+osas que debemos observar7 /. La clase deriva de +ontroller 2. (iene un mGtodo pEblico que devuelve un #ctionDesult y que se llama 5ndex. 'sto es una accin. +ualquier mGtodo pEblico de un controlador es por defecto una accin. 'n #$%.&'( )*+ toda peticin del nave2ador debe ser enrutada a una peticin 1mGtodo pEblico3 de un controlador. %or defecto se si2ue la convencin de que las HDLs est6n en la forma http788servidor8controlador8accion. 's decir, para invocar la accin 5ndex, del controlador Fome, usaremos la HDL7 http788servidor8Fome85ndex. -iBaos en un detalle importante7 la clase se llama Fome+ontroller pero el nombre del controlador es Fome 1sin +ontroller3

Creacin de la %ista asociada


'l cdi2o de la accin que 2enera *isual $tudio 1return *ie 13P3 lo que hace es devolver la vista asociada a dicha accin. N aqu" debemos tener presente otra convencin de #$%.&'( )*+. +omo se ha dicho antes las vistas cuel2an de la carpeta 8*ie s. %or defecto, las vistas de un controlador7 /. 'st6n en una subcarpeta con el nombre del controlador 2. $e llaman i2ual que la accin 's decir, la vista de la accin 5ndex del controlador Fome, estar6 en la carpeta 8*ie s8Fome y se llamar6 5ndex. #s" pues creamos la carpeta 1#dd &e -older3 Fome dentro de *ie s y para aadir la vista, clic! con el botn derecho sobre la carpeta reciGn creada en el $olution 'xplorer y #dd O *ie . 'so nos desplie2a el di6lo2o de nueva vista7

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com

Le ponemos J5ndexJ como nombre y le damos a #dd. +on eso *isual $tudio nos habr6 2enerado un archivo 5ndex.cshtml 1situado en 8*ie s8Fome3 con el cdi2o7
#{ Vie $a%&Title ' (Index(! " )*+,Index)/*+,

#hora modificamos el cdi2o F()L para aadir el Fello 4orld7


#{ Vie $a%&Title ' (Index(! " )*+,Index)/*+, Hola mundo& -aludos desde )stron%,A-.&/ET 0VC)/stron%,

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com N listosQ +on esto ya tenemos nuestra aplicacin lista. %ara probarla basta eBecutarla 1con -<3 y comprobar los resultados7

Hn Eltimo detalle7 $i os fiB6is la HDL es simplemente http788localhost, sin nada m6s y se est6 mostrando nuestra vista. LRuG ha ocurrido9 %ues que, por defecto si no se incluye controlador se asume que es JFomeJ y si no se entra accin se asume que es 5ndex. %ero si entramos la HDL completa vemos que tambiGn funciona7

%or otra parte si entramos un nombre de controlador o de accin que no existe, recibimos un .0. 1p62ina no encontrada37

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com SHn saludo a todosQ
Artculo por

Eduard Toms

Pasar datos de los controladores a las %istas


En este art"culo $amos a $er como pasar datos desde los controladores a las $istas. Fay tres mGtodos 1que realmente son dos3 principales para pasar datos de los controladores a las vistas. Decordad que se2En el patrn )*+, el controlador es quien accede al modelo para obtener los datos y mand6rselos a la vista. La vista debe limitarse a mostrar esos datos 1o a pedir datos nuevos y mand6rselos de vuelta al controlador, lo que veremos m6s adelante3. Los datos que el modelo proporciona al controlador pueden venir de cualquier fuente 1usualmente una base de datos3.

Primer m&todo' Vie()ata


'l primero de los mGtodos es el denominado *ie Data. *ie Data es un diccionario de clave 1una cadena3 ; valor 1un obBeto3 que el controlador pasa a la vista. Hn eBemplo de uso de *ie Data es el si2uiente controlador7
public class HomeController : Controller { public ActionResult Index() { Vie 1ata2(/ombre(3 ' (Eduard Tom4s(! Vie 1ata2(T itter(3 ' (eiximenis(! return Vie ()! " "

#qu" se define el controlador Fome con la accin 5ndex 1recordad que las acciones son los mGtodos pEblicos que reciben las peticiones del nave2ador3. 'n esta accin establecemos las claves &ombre y ( itter del *ie Data y lue2o devolvemos la vista asociada a dicha accin. %ara mostrar los datos en la vista, simplemente usamos la propiedad *ie Data que tienen las vistas y que funciona exactamente i2ual. 'n este caso, en el cdi2o de nuestra vista 1archivo Fome.cshtml que estar"a en la carpeta Fome dentro de la carpeta *ie s3 tendr"amos al2o como7
)*+,Index)/*+, 0i nombre es #Vie 1ata2(/ombre(3 5 puedes se%uirme en )a *re6'(*ttp://t itter&com/#Vie 1ata2(T itter(3(,T itter)/a,&

-iBaos en dos cosas7 /. %ara acceder a un valor del *ie Data, simplemente usamos *ie DataTJclaveJU. 2. N muy importante7 el uso de la arroba 1V3 antes de llamar a *ie Data. 'so es parte de la sintaxis Da?or 1que veremos con detalle m6s adelante, as" que de momento no nos vamos a preocupar mucho de ella3. 'l uso de *ie Data tiene dos puntos dGbiles que deben tenerse presentes7 /. Las claves son cadenas, por lo que si nos equivocamos el compilador no puede ayudarnos. (ampoco herramientas de refactorin2 pueden darnos soporte. 2. *ie DataTJclaveJU siempre devuelve un obBect por lo que debemos ir haciendo castin2 si queremos obtener el tipo real de lo que hay almacenado. %.eB. 'n un controlador ponemos el si2uiente valor en *ie Data7
Vie 1ata2(7ec*aAlta(3 ' ne 1ateTime(+889: ;+: ;8)!

'ste valor es un Date(ime, no obstante si desde la vista queremos llamar a los mGtodos de Date(ime 1como

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

10

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com (oLon2Date$trin2133 deberemos hacer un castin27 Dado de alta en7 V111Date(ime3*ie DataTJ-echa#ltaJU3.(oLon2Date$trin2133 $i no hiciGramos el castin2 a Date(ime, la llamada a (oLon2Date$trin213 2enerar"a una excepcin 1aun cuando, en efecto, lo que hay en el *ie DataTJ-echa#ltaJU es un Date(ime3.

Se*undo m&todo' Vie(+a*


*ie Ca2 funciona de forma muy parecida a *ie Data. #l i2ual que *ie Data, *ie Ca2 es un diccionario de clave ; valor. %ero se aprovecha de las capacidades de pro2ramacin din6mica que ofrece +W ., para en lu2ar de usar cadenas para especificar la clave, usar propiedades. #s", desde una accin podemos hacer7
public ActionResult Index+() { Vie $a%&/ombre ' (Eduard Tom4s(! Vie $a%&T itter ' (eiximenis(! Vie $a%&7ec*aAlta ' ne 1ateTime(+889: ;+: ;8)! return Vie ()! "

-iBaos que el cdi2o es casi i2ual al uso de *ie Data, solo que en lu2ar de hacer *ie DataTJclaveJU hacemos *ie Ca2.clave. N para recuperarlos desde una vista9 %ues i2ual que antes, podemos usar la propiedad *ie Ca27
)*+,Index+)/*+, 0i nombre es #Vie $a%&/ombre 5 puedes se%uirme en )a *re6'(*ttp://t itter&com/#Vie $a%&T itter(,T itter)/a,& )br /, 1ado de alta en: #Vie $a%&7ec*aAlta&To<on%1ate-trin%()

#qu" podemos ver la 2ran ventaBa de *ie Ca2 respecto *ie Data7 no es necesario usar castin2. -iBaos que para usar (oLon2Date$trin213 no hemos tenido necesidad de convertir el resultado devuelto por *ie Ca2.-echa#lta a Date(ime. 'sa es la 2ran ventaBa de *ie Ca2 respecto a *ie Data y es por eso que, personalmente, os recomiendo usar *ie Ca2 en lu2ar de *ie Data 1de hecho *ie Data se mantiene por compatibilidad con las versiones anteriores del frame or! de #$%.&'( )*+3. Itra ventaBa es que no usamos cadenas sino propiedades para acceder a los elementos, pero oBo, que el compilador no puede ayudaros si accedGis a una clave 1propiedad3 que no existe 1al ser las propiedades din6micas3.

Tercer m&todo' Model tam,i&n conocido como Vie(Model!


'l tercer mGtodo para pasar informacin de una accin de un controlador a una vista, es usando la propiedad )odel. La propiedad )odel no funciona como las anteriores, sino que lo que se pasa es un obBeto, que se manda de la accin hacia la vista. # diferencia de *ie Data y *ie Ca2 que existen tanto en el controlador como en la vista, el controlador no tiene una propiedad )odel. 'n su lu2ar se usa una sobrecar2a del mGtodo *ie 13 y se manda el obBeto como par6metro7
public { public public public " class =suario strin% /ombre { %et! set! " strin% T itter { %et! set! " 1ateTime Alta { %et! set! "

public class HomeController : Controller { public ActionResult Index>() { =suario data ' ne =suario()! data&/ombre ' (Eduard Tom4s(! data&T itter ' (eiximenis(! data&Alta ' ne 1ateTime(+889: ;+: ;8)! return Vie (data)! " "

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

11

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com &otemos las diferencias7 'l controlador crea un obBeto de la clase Hsuario y manda ese obBeto a la vista, pas6ndolo como par6metro a la funcin *ie . LN desde la vista9 %ues usamos la propiedad )odel para acceder a dicho obBeto7
#model 0?cHello@orld&Controllers&=suario )*+,Index>)/*+, 0i nombre es #0odel&/ombre 5 puedes se%uirme en )a *re6'(*ttp://t itter&com/#0odel&T itter(,T itter)/a,& )br /, 1ado de alta en: #0odel&Alta&To<on%1ate-trin%()

-iBaos que ahora usamos )odel para acceder a los datos, en lu2ar de *ie Data o *ie Ca2. N una cosa importante7 fiBGmonos en la primera l"nea, que empie?a con Vmodel. 'sa l"nea le indica al frame or! de que tipo es el obBeto que la vista recibe del controlador 1es decir, de que tipo es la propiedad )odel3. %or supuesto este tipo debe coincidir con el obBeto que se pasa como par6metro a la funcin *ie en la accin del controlador. Hna nota7 'l uso de Vmodel es opcional, si no lo ponemos, nuestra vista puede se2uir usando la propiedad )odel, pero en este caso es de tipo dynamic. 'so tiene sus ventaBas y sus inconvenientes 1volveremos sobre ello en posteriores art"culos3. Las vistas que declaran Vmodel, se llaman vistas fuertemente tipadas. Hsar vistas fuertemente tipadas tiene una ventaBa que es que al saber *isual $tudio cual es el tipo de la propiedad )odel, nos puede proporcionar soporte de 5ntellisense. Hsar este mecanismo es la manera preferida de pasar datos desde una accin a una vista 1ya que en lu2ar de tener datos desperdi2ados en n claves los podemos tener or2ani?ados en una clase3. # las clases que se pasan desde las acciones a las vistas 1como nuestra clase Hsuario3 se les conoce tambiGn con el nombre de *ie )odels 1para distin2uirlas de las clases que conforman el )odelo del patrn )*+, ya que los *ie )odels lo Enico que hacen es contener datos que mostrar6 una vista3.

-na nota .inal


#l principio del art"culo he comentado que ver"amos tres mGtodos que en realidad eran dos. L# que me refer"a9 %ues b6sicamente a que *ie Ca2 y *ie Data son dos maneras distintas para acceder al mismo conBunto de datos. 's decir, si establecemos el valor de *ie DataTJ&ombreJU podemos leerlo con *ie Ca2.&ombre y viceversa. De ah" que haya comentado que eran tres mGtodos, que realmente eran dos. %ara m6s informacin os recomiendo el art"culo de KosG ). #2uilar sobre el tema, que podGis leer en7 http788 .variablenotfound.com820/08/28vie ba2;en;aspnet;mvc;,.html Hn saludo a todosQ %D7 +omentaros solamente que el cdi2o fuente de todos los art"culos de esta serie sobre #$%.&'( )*+ lo podrGis encontrar en7 http788cid;=<2/c2<9e9b/bec=.office.live.com8bro se.aspx8desarrollo eb;aspnetmvc
Artculo por

Eduard Toms

El motor de %istas /a0or


Anali(amos la sinta+is ) sus consideraciones para el motor de $istas ,a(or en .NET. Desde su versin #$%.&'( )*+ ha tenido el concepto de motor de vistas 1*ie 'n2ine3. # ver, recapitulemos7 en #$%.&'( )*+ las vistas reali?an tareas slo de presentacin. &o contienen nin2En tipo de l2ica de ne2ocio y no acceden a datos. C6sicamente se limitan a mostrar datos 1en el art"culo anterior vimos como pasar datos de los controladores a las vistas3 y a solicitar datos nuevos al usuario. $i vienes del mundo de ebforms, olv"date del concepto de 4eb +ontrols7 no existen en #$%.&'( )*+. &o tenemos dra2 and drop, no confi2uramos propiedades. Las vistas son b6sicamente F()L. N lo que no es F()L son pequeas porciones de cdi2o de servidor destinadas a terminar 2enerando F()L para mostrar informacin. 'l equipo que desarroll #$%.&'( )*+ tuvo la feli? idea de permitir separar la sintaxis de servidor usada, del frame or! de #$%.&'( )*+. L'l resultado9 Lo que llamamos un motor de vistas de #$%.&'( )*+. 'n las versiones / y 2, el frame or! viene con un Enico motor de vistas, el llamado motor #$%M, que usa los cl6sicos archivos .aspx como vistas de #$%.&'( )*+. %ero SoBoQ #unque estemos utili?ando archivos .aspx, no son ebforms 1los ebcontrols no funcionan, no

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

12

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com tenemos vie state ni el ciclo de vida de ebforms y adem6s es que@ son vistas de )*+, por lo que slo deben hacer tareas de presentacin3. La sintaxis que usa el motor #$%M es un poco@ eso que los an2losaBones llaman verbose, es decir que se debe escribir mucho para ciertas tareas. #s", ima2inad una p62ina que tuviese que mostrar una lista de elementos de la clase Hsuario 1la que usamos en el cap"tulo anterior3. 'l cdi2o, usando el motor de vistas #$%M queda as"7
)A# .a%e Title'(( <an%ua%e'(CB( 0aster.a%e7ile'(C/Vie s/-*ared/-ite&0aster( In*erits'(-5stem&@eb&0?c&Vie .a%e)IEnumerable)0?cHello@orld&Controllers&=suario,,( A, )asp:Content I1'(Content;( Content.laceHolderI1'(TitleContent( runat'(ser?er(, 1emoAspx )/asp:Content, )asp:Content I1'(Content+( Content.laceHolderI1'(0ainContent( runat'(ser?er(, )*+,1emoAspx)/*+, )table, )A 6oreac* (?ar item in 0odel) { A, )tr, )td, )A: item&/ombre A, )/td, )td, )A: item&T itter A, )/td, )td, )A: -trin%&7ormat(({8:%"(: item&Alta) A, )/td, )/tr, )A " A, )/table, )/asp:Content,

-iBaos en la cantidad de veces que debe usarse el ta2 XY y su pareBo YZ para indicar dnde empie?a y termina el cdi2o de servidor. D6pidamente empe?aron a sur2ir motores de vistas alternativos, reali?ados por la comunidad, con la intencin de tener sintaxis m6s claras para nuestras vistas. #l2unos eBemplos son &haml y $par!. -inalmente la versin , de #$%.&'( )*+ vino acompaada de un nuevo motor de vistas, llamado Da?or. 'so s", el motor #$%M puede se2uir siendo usado en #$%.&'( )*+,, pero honestamente no hay nin2una ra?n para hacerlo 1salvo en casos de mi2raciones, por supuesto37 Da?or es m6s claro, sencillo e intuitivo.

Sinta1is de /a0or
Lo que m6s choca de Da?or es que, a diferencia del motor #$%M donde tenemos el ta2 que inicia el cdi2o de servidor y el que lo termina, slo hay ta2 para iniciar cdi2o de servidor. 'l motor Da?or es lo suficientemente inteli2ente para saber cu6ndo termina el cdi2o de servidor, sin necesidad de que lo explicitemos. *eamos la misma vista de antes, pero ahora usando Da?or7
#model IEnumerable)0?cHello@orld&Controllers&=suario, #{ Vie $a%&Title ' (1emoRaDor(! " )*+,1emoRaDor)/*+, #6oreac* (?ar item in 0odel) { )tr, )td, #item&/ombre )/td, )td, #item&T itter )/td, )td, #-trin%&7ormat(({8:%"(: item&Alta) )/td, )/tr, " )/table,

Las diferencias saltan a la vista, Lno9 'n Da?or el s"mbolo de la arroba 1V3 marca el inicio de cdi2o de servidor. N como

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

13

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com comentaba antes, no hay s"mbolo para indicar que se termina el cdi2o de servidor7 el motor Da?or deduce cuando termina en base al contexto. -iBaos que para mostrar una variable de servidor 1item.&ombre p.eB.3 simplemente la precedemos de una V. -iBaos tambiGn que la llave de cierre del foreach no debe ser precedida de nin2una arroba, Da?or ya sabe que esa llave es de servidor y cierra el foreach abierto. 'l uso de la V funciona de dos maneras b6sicas7 /. Vexpresin7 Denderi?a la expresin en el nave2ador. #s" Vitem.&ombre muestra el valor de "tem.&ombre. 's decir Vexpresin equivale a XY7 expresin YZ 2. V[ cdi2o \7 %ermite eBecutar un cdi2o que no 2enera salida F()L. 's decir V[cdi2o\ equivale a XY +di2o YZ

Consideraciones a la sinta1is
Expresiones compejas +omo hemos visto el motor Da?or interpreta cuando empie?a y cuando termina el cdi2o de servidor. %ero no siempre lo consi2ue adecuadamente. %.eB, el si2uiente cdi2o Da?or7 V[ int a : /0P int b : ,P \ 'l valor de /0 ; , es7 Va;b ]enera el si2uiente F()L7 'l valor de /0 ; , es7 /0;b 's decir Da?or ha interpretado que el cdi2o de servidor terminaba al encontrar el s"mbolo de resta. 'n este caso, esa presuncin es totalmente errnea, pero por suerte podemos usar los parGntesis para que haya slo una expresin detr6s de la arroba7 'l valor de /0 ; , es7 V1a;b3 +on ese cdi2o la vista mostrar6 el valor correcto 1A3. Decordad la clave7 el motor Da?or espera una y slo una expresin detr6s de la V. %or eso debemos usar los parGntesis. "Romper" el cdigo de servidor # veces la problem6tica es Busto la contraria de la que hemos visto con las expresiones compleBas7 a veces hay cdi2o que Da?or interpreta que es de servidor pero realmente parte de ese cdi2o es F()L que debe enviarse al cliente. *eamos un eBemplo7
#6or (int i ' 8! i ) ;8! iEE) { El ?alor de i es: #i )br /, "

# priori podr"amos esperar que este cdi2o 2enerara /0 l"neas de cdi2o F()L. %ero el resultado es un error de compilacin. La ra?n es que Da?or interpreta que la l"nea J'l valor de i es7 ViJ es cdi2o de servidor. %ara JromperJ este cdi2o de servidor y que Da?or JsepaJ que realmente esto es cdi2o que debe enviarse tal cual al cliente, tenemos dos opciones7 /. 5ntercalar una etiqueta F()L. #l intercalar una etiqueta F()L Da?or Jse da cuentaJ que all" empie?a un cdi2o de cliente7
#6or (int i ' 8! i ) ;8! iEE) { )span,El ?alor de i es:)/span, #i )br /, "

2. Hsar la construccin V7 que indica expl"citamente a Da?or que lo que si2ue es cdi2o de cliente7
#6or (int i ' 8! i ) ;8! iEE) { #:El ?alor de i es: #i )br /, "

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

14

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com La diferencia es que en el primer caso las etiquetas se env"an al nave2adaor, mientras que en el se2undo caso no.

Consideraciones en correos electrnicos


La 2ente que ha desarrollado el motor Da?or ha tenido en cuenta una excepcin para los correos electrnicos. 's decir, Da?or es de nuevo, lo suficientemente inteli2ente para saber que una expresin es un correo electrnico. #s" pues el si2uiente cdi2o no da error y env"a el F()L esperado al cliente7
En?iame un mail: a usuario#ser?idor&com

'n este caso Da?or interpreta que se trata de un correo electrnico, por lo que no trata la V como inicio de cdi2o de servidor. 'ste comportamiento a veces tampoco se desa. %.eB, ima2inad lo si2uiente7
)di? id'(di?F#0odel&Index(,1i? usado)/di?,

'stoy asumiendo que el *ie )odel que recibe la vista tiene una propiedad llamada 5ndex. $upon2amos que dicha propiedad 1)odel.5ndex3 vale /0. La verdad es que uno pensar"a que eso 2enerar"a el cdi2o F()L7
)di? id'(di?F;8(,1i? usado)/di?,

%ero el resultado es bien distinto. 'l cdi2o F()L 2enerado es7


)di? id'(di?F#0odel&Index(,1i? usado)/di?,

's decir, Da?or no ha interpretado la V como inicio de cdi2o de servidor, y eso es porque ha aplicado la excepcin de correo electrnico. La solucin pasa por usar los parGntesis7
)di? id'(di?F#(0odel&Index)(,1i? usado)/di?,

#hora Da?or sabe que )odel.5ndex es cdi2o de servidor y lo evaluar6, 2enerando el F()L que est6bamos esperando. # veces Da?or falla incluso m6s espectacularmente. Dado el si2uiente cdi2o7
#6or (int i ' 8! i )' ;! iEE) { )di? id'(di?F#i(,1i? #i)/di?, "

'n base a lo que hemos visto podr"amos esperar que 2enerase el si2uiente F()L7
)di? id'(di?F#i(,1i? 8)/di?, )di? id'(di?F#i(,1i? ;)/di?,

%ues SnoQ 'ste cdi2o hace que el motor de Da?or de un error 1(he for bloc! is missin2 a closin2 J\J character. )a!e sure you have a matchin2 J\J character for all the J[J characters ithin this bloc!, and that none of the J\J characters are bein2 interpreted as mar!up3. %or supuesto, la solucin para 2enerar el F()L que queremos pasa por usar el parGntesis i2ual que antes7
#6or (int i ' 8! i )' ;! iEE) { )di? id'(di?F#(i)(,1i? #i)/di?, "

]enera el F()L esperado7


)di? id'(di?F8(,1i? 8)/di?, )di? id'(di?F;(,1i? ;)/di?,

Escapar la arroba # veces es necesario indicarle a Da?or que una arroba es eso@ una simple arroba y que no ha2a nada espec"fico. Rue no asuma nada, que no piense nada, que simplemente env"e una V al cliente. LHn eBemplo9 'l si2uiente cdi2o7
)st5le, ##media screen { bod5 { 6ontGsiDe: ;>px!" " )/st5le,

$i no us6ramos la doble arroba 1VV3, Da?or nos 2enerar"a un error, ya que Vmedia lo interpreta como Jenviar el contenido

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

15

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com de la variable media al clienteJ. 'n este caso al usar VV Da?or simplemente sabe que debe enviar una V al cliente y lo que el nave2ador recibe es7
)st5le, #media screen { bod5 { 6ontGsiDe: ;>px!" " )/st5le,

Conclusiones
Femos visto la sint6xis b6sica del motor de vistas Da?or, y las principales consideraciones que debemos tener presentes. &o hemos visto las capacidades adicionales de dicho motor de vistas como layouts, templates y re2iones que iremos viendo en cap"tulos posteriores. %ara finali?ar una cosilla7 #mbos motores de vistas 1#$%M y Da?or3 se pueden usar en )*+, de forma simult6nea. 'l motor de #$%.&'( )*+ intentar6 encontrar primero una vista .aspx y si no la encuentra buscar6 una vista Da?or 1.cshtml, aunque tambiGn puede ser .vbhtml si usamos *isual Casic.&'( en lu2ar de +W3. #unque por supuesto este comportamiento puede ser modificado. SHn saludo a todosQ
Artculo por

Eduard Toms

Ta,la de rutas 2 Parte 3


-a tabla de rutas en el framework ASP .NET MVC sir$e para mapear las .,-s de la aplicacin a sus correspondientes controladores ) acciones dentro de ellos. 'n estos primeros cuatro cap"tulos de esta serie sobre #$%.&'( )*+ hemos visto los aspectos fundamentales del frame or!7 controladores, acciones y vistas. 'n el cap"tulo dos, vimos que cada peticin del nave2ador debe ser enrutada a una accin de un controlador. DiBimos tambiGn que por defecto se si2ue la convencin de que las HDLs est6n en forma http788servidor8controlador8accion. Lo que mucha 2ente no sabe es que eso no es realmente una convencin del frame or! de #$%.&'( )*+ ni mucho menos una obli2acin. Rue las HDLs si2an por defecto esta forma se debe, ni m6s ni menos, al cdi2o que nos 2enera por defecto *isual $tudio cuando creamos un proyecto #$%.&'( )*+. La responsable de decidir quG accin de quG controlador se encar2a de procesar cada peticin es la tabla de rutas y es de lo que vamos a hablar hoy. Fablando r6pidamente podr"amos decir que la tabla de rutas es la responsable de mapear cada HDL a una accin de un controlador. La frase puede parecer balad", pero no lo es en absoluto. Fay dos aspectos clave a tener en cuenta7 /. +ada HDL debe ser mapeada a una accin de un controlador en concreto. 2. %ara mapear una peticin del nave2ador a una accin de un controlador se usa slo la HDL. Depito7 slo la HDL. Fablando en propiedad, la frase anterior no es del todo precisa. Lo que la tabla de rutas realmente hace es determinar quG valores de ruta 1route values3 se rellenan a partir de la HDL. Lo que nos lleva a pre2untarnos, que son los valores de ruta.

Valores de ruta route %alues!


Los valores de ruta no son m6s que un conBunto de valores 1par6metros si prefer"s3 cuyo valor se extrae a partir de la peticin que reali?a el nave2ador, concretamente a partir de la HDL. %uede haber todos los valores de ruta que se quiera, pero hay dos que deben ser establecidos siempre por cada HDL7 /. controller7 Debe contener el nombre del controlador que 2estionar6 la peticin 2. action7 Debe contener el nombre de la accin que 2estionar6 la peticin

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

16

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com 'sos dos valores los espera el frame or! siempre, para as" poder enrutar dicha peticin hacia una accin de un controlador. %ero al mar2en de esos dos, pueden existir otros valores de ruta. N LquG hace el frame or! con el resto de valores de ruta9 %ues los 2uarda y los env"a a la accin que 2estiona la peticin. La tabla de rutas es pues la responsable de, decidir, por cada HDL, que valores de ruta, y con quG valor real, se rellenan. Decordad que controller y action son obli2atorios y que son usados por el frame or! para, precisamente, decidir quG accin de quG controlador 2estiona la peticin, de ah" que se di2a comEnmente, que la tabla de rutas mapea HDLs a acciones, aunque como hemos visto, realmente hace al2o m6s.

Con.i*uracin de la ta,la de rutas


La tabla de rutas no tiene valores por defecto. 's decir, inicialmente est6 vac"a y eso si2nifica que no hay nin2una peticin que se pueda enrutar. 's el propio *isual $tudio, quien nos 2enera cdi2o para confi2urar la tabla de rutas, con unos valores iniciales. N esos valores son los que hacen que las HDLs ten2an la forma conocida de http788servidor8controlador8accion. $i abr"s *isual $tudio y cre6is un proyecto #$%.&'( )*+ nuevo 1incluso si ele2"s la opcin de 'mpty3, verGis el si2uiente cdi2o en el archivo ]lobal.asax.cs7
public static ?oid Re%isterRoutes(RouteCollection routes) { routes&I%noreRoute(({resource"&axd/{Hpat*In6o"()! routes&0apRoute( (1e6ault(: // Route name ({controller"/{action"/{id"(: // =R< it* parameters ne { controller ' (Home(: action ' (Index(: id ' =rl.arameter&Iptional " // .arameter de6aults )! "

'ste cdi2o es el que confi2ura la tabla de rutas. 'l par6metro routes que recibe este mGtodo es la propia tabla de rutas, que est6 en la propiedad est6tica Doutes de la clase Doute(able. #nalicemos este cdi2o, y empecemos no por la primera l"nea, sino por la se2unda7 la que llama al mGtodo )apDoute. 'ste mGtodo 1que es realmente un mGtodo de extensin, aunque esto no sea relevante3 nos permite aadir una nueva entrada a la tabla de rutas de forma sumamente sencilla. 'st6 sobrecar2ado pero en este cdi2o los par6metros que recibe son7 /. 'l nombre de la ruta 1un identificador de la ruta3. 'n este caso la ruta se llama Default 2. Las HDLs que mapea esta ruta ,. Los valores por defecto de los valores de ruta, en caso de no ser encontrados en la HDL.

Patrones de -/#s
+entrGmonos un poco en se2undo par6metro. $u valor es ^[controller\8[action\8[id\_. 'so es simplemente el patrn que deben cumplir las HDLs para ser procesadas por esta ruta. Lo que est6 entre llaves es el nombre del valor de ruta que se crea. #s" pues el patrn [controller\8[action\8[id\ mapear6 cualquier HDL que estG en la forma http788servidor8xxx8yyy8???. N adem6s asi2nar6 los si2uientes valores de ruta7 /. controller : xxx 2. action : yyy ,. id : ??? %ero@ que pasa con una HDL que no ten2a el 8??? final9 Rue ocurre con una HDL http788servidor8xxx8yyy9 %ues en principio una HDL de este tipo no ser"a procesada por este patrn 1ya que el patrn pide expl"citamente que haya [controller\8[action\8[id\. %ero, para evitar que la confi2uracin de la tabla de rutas costase horrores, existe el tercer par6metro7 los valores por defecto.

Valores $or de.ecto


'l tercer par6metro de )apDoute son los valores por defecto de los valores de ruta. 's decir, si el valor de ruta no puede sacarse a partir del patrn de HDL especificado, se asumir6 dicho valor. $e define como un obBeto annimo cuyas propiedades tienen el nombre de los valores de ruta y el valor de dicha propiedad es el valor por defecto del valor de ruta. 'n nuestro caso est6 definido como7

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

17

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com


ne { controller ' (Home(: action ' (Index(: id ' =rl.arameter&Iptional "

%or lo tanto tenemos que7 'l valor de ruta ^controller_ vale ^Fome_ por defecto. 'l valor de ruta ^action_ vale ^5ndex_ por defecto 'l valor de ruta ^id_ es opcional. 's decir si no aparece no se crear6 1no existir63. &o es que val2a null, 0, cadena vac"a o cualquier otro valor vac"o, no. $implemente no se crear6.

*isto esto, ahora podemos ver que7 /. http788servidor8Coo!s8*ie 8/0 se procesar6 y los valores de ruta ser6n /. controller : Coo!s 2. action : *ie ,. id : /0 2. http788servidor8Coo!s se procesar6 y los valores de ruta ser6n /. controller : Coo!s 2. action : 5ndex 1valor por defecto3 ,. id : &o existir6 el valor de ruta ^id_ ,. http788servidor se procesar6 y los valores de ruta ser6n /. controller : Fome 1valor por defecto3 2. action : 5ndex 1valor por defecto3 ,. id : &o existir6 el valor de ruta ^id_ .. http788servidor8Coo!s8*ie 8/0820 &o ser6 procesada por la tabla de rutas. 'sta HDL no puede mapearse al patrn [controller\8[action\8[id\ $i una HDL no puede ser procesada por la tabla de rutas, el frame or! devuelve un error http .0. 1p62ina no encontrada3.

M4lti$les $atrones
La tabla de rutas se llama precisamente tabla porque puede contener varias entradas 1es decir, varios patrones de HDL, con sus par6metros por defecto, etc3. %ara aadir m6s entradas 1rutas, cada entrada se conoce como ruta3, lo m6s sencillo es aadir llamadas a )apDoute. %.eB. si quisiGramos procesar la HDL anterior http788servidor8Coo!s8*ie 8/0820 podr"amos aadir una entrada adicional7
routes&0apRoute( (1osIds(: // Route name ({controller"/{action"/{id"/{id+"( )!

#hora la HDL http788servidor8Coo!s8*ie 8/0820 ya puede ser procesada, y ser6 procesada por esa entrada nueva en la tabla de rutas. Los valores de ruta creados ser6n7 controller : Coo!s action : *ie id : /0 id2 : 20

Hn tema importante es que el orden de las rutaas en la tabla de rutas importa. %or cada HDL, el frame or! evaluar6 las distintas entradas de la tabla de rutas, una a una, en el orden en que estas se encuentren y tan buen punto una HDL pueda ser procesada, se eli2ir6 esa entrada de la tabla de rutas. %.eB. supon2amos que queremos mapear las HDLs de la forma http788servidor8*er8'du a la accin *ie del controlador %rofile con un valor de ruta llamado user cuyo valor sea lo que hay despuGs de *er 1'du en este caso3. 'so lo podemos conse2uir con una entrada en la tabla de rutas7
routes&0apRoute( (Vie .ro6ile(: // /ombre de la ruta (Ver/{aut*or"(: // =R< it* parameters ne { controller ' (.ro6ile(: action ' (Vie ( " )!

Hn detallito a tener en cuenta de esta nueva entrada es que dado que no hay lu2ar en el patrn de HDL para los valores de ruta de controller y action, al ser esos obli2atorios, deben especificarse como valores por defecto.

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

18

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com 'sta entrada mapea una HDL del tipo7 http788servidor8*er8'du con los valores de ruta7 controller : %rofile 1valor por defecto3 action : *ie 1valor por defecto3 author : 'du 1sacado del patrn de la HDL3

%ero, podGis comprobar que si aad"s esa l"nea despuGs del routes.)apDoute que ya hab"a, si entr6is una HDL del tipo http788servidor8*er8'du el frame or! os devolver6 un .0., incluso aunque ten26is el controlador %rofile con una accin *ie definida. L%or quG9 %ues simplemente porque la tabla de rutas se evalEa en orden. N Lpuede mapear la primera entrada 1la ruta llamada Default3 una HDL del tipo http788servidor8*er8'du9 La respuesta es que s", y los valores de ruta quedan establecidos a7 controller : *er action : 'du id : &o hay valor de ruta ^id_ 1recordad que era opcional3

%or lo tanto, a no ser que ten26is un controlador llamado *er con una accin llamada 'du 1cosa poco probable, no nos vamos a en2aar 7p3 el frame or! os devolver6 un .0.. %ara que todo funcione, la entrada ^Default_ debe estar despuGs de la nueva entrada7
public static ?oid Re%isterRoutes(RouteCollection routes) { routes&I%noreRoute(({resource"&axd/{Hpat*In6o"()! routes&0apRoute( (Vie .ro6ile(: // /ombre de la ruta (Ver/{aut*or"(: // =R< it* parameters ne { controller ' (.ro6ile(: action ' (Vie ( " )! routes&0apRoute( (1e6ault(: // Route name ({controller"/{action"/{id"(: // =R< it* parameters ne {controller ' (Home(: action ' (Index(: id ' =rl.arameter&Iptional" // .arameter de6aults )! "

I*norar $atrones de -/#


# veces es necesario que ciertas peticiones con una determinada HDL, no sean 2estionadas por el frame or! de #$%.&'( sino por el propio motor de #$%.&'( o bien el propio 55$. Hn eBemplo podr"a ser una peticin a una ima2en. 'n este caso, no vamos a querer un controlador que nos devuelva la ima2en, es mucho meBor deBar que sea el propio 55$ quien lo ha2a 1ser6 mucho m6s eficiente3. %or ello el frame or! permite definir rutas de exclusin, es decir rutas que si mapean una determinada HDL, dicha peticin ser6 i2norada por #$%.&'( )*+. %ara crear esas rutas especiales, se usa el mGtodo 52noreDoute. $e le suele pasar un solo ar2umento, que es el patrn de HDL a i2norar. Hn eBemplo lo tenemos en el propio cdi2o que 2enera *isual $tudio7
routes&I%noreRoute(({resource"&axd/{Hpat*In6o"()!

'ste patrn de HDL se mapear6 a todas aquellas HDLs que ten2an la forma http788servidor8xxx.axd8yyy Dnde7 /. xxx es cualquier nombre 2. yyy es cualquier cosa, incluyendo barras separadoras 183. 'l hecho de que yyy pueda incluir barras separadoras es porque se usa la forma [`nombreavaloraruta\ 1con un asterisco3 que es lo que se conoce como catch;all y si2nifica literalmente7 captura todos los caracteres de la HDL que ven2an a partir de ahora. 's decir la HDL http788servidor8trace.axd8foo8bar8ba? ser6 enrutada por esta ruta. #l ser declarada con 52noreDoute, lo que har6 es que dicha peticin sea i2norada por #$%.&'( )*+ y ser6 procesada por al2uien m6s 1en este caso el propio motor de #$%.&'(, pero eso ya depende de cada caso3.

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

19

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com 'n el si2uiente art"culo vamos a ver los valores de ruta y los controladores.
Artculo por

Eduard Toms

Ta,la de rutas 2 Parte 5


Se!unda parte de las e+plicaciones relati$as a la tabla de rutas de ASP .NET MVC, un componente b/sico &ue podemos confi!urar para personali(ar totalmente las .,-s de las aplicaciones web.

Valores de ruta y controladores


Femos visto que hay dos valores de ruta 1^controller_ y ^action_3 que deben ser establecidos a partir de cada HDL. %ero@ LquG ocurre con el resto de valores de ruta que establecemos9 1como p.eB. el ^id_ o el ^authorJ de los eBemplos anteriores3. %ues, simplemente, esos valores son pasados a los controladores, donde pueden ser consultados de varias formas, siendo una de las m6s comunes que estGn como par6metros en las acciones. %.eB. en el caso del valor de ruta author, la accin *ie del controlador %rofile podr"a estar declarada tal y como si2ue7
public class .ro6ileController : Controller { 2Action/ame((Vie ()3 public ActionResult Ver(strin% aut*or) { return Vie ()! " " Nota: 'n este caso usamos el atributo T#ction&ameU que permite indicar el nombre de la accin que implementa un mGtodo en concreto. $i no se usa ese atributo el nombre de la accin es el mismo que el nombre del mGtodo. 'n este caso debemos usarlo porque la accin se llama *ie , pero el nombre de mGtodo *ie ya est6 definido dentro de la clase +ontroller 1y se usa para devolver vistas3.

%odemos ver como la accin *ie recibe el par6metro ^authorJ, cuyo valor ser6 valor de ruta con el mismo nombre 1autor3. 's decir, en el caso de la HDL http788servidor8*er8'du el valor del par6metro author ser6 precisamente ^'du_. 'n el caso de par6metros opcionales, la cosa es un pel"n m6s delicada. $upon2amos que tenemos la si2uiente accin7
public class HomeController : Controller { public ActionResult Index(int i) { return Vie ()! " "

$upon2amos que esta accin se ha mapeado a partir de la entrada ^Default_ de la tabla de rutas. $i entramos una url del tipo http788servidor8Fome85ndex8/0 no hay problema porque el valor de ^id_ es /0. %ero, en este caso id es un par6metro opcional, y que ocurre si entramos la HDL http788servidor8Fome85ndex9 Decordad que un par6metro opcional, si no aparece simplemente no se crea. &o es que val2a 0 ^_ o null. 's que no se crea. %or lo tanto si entramos una HDL de tipo http788servidor8Fome85ndex recibiremos un error7

'l error viene a decir que la accin espera un par6metro 1id3 pero que no hay valor de ruta del cual tomar ese par6metro. $i el par6metro aceptase null 1es decir, fuese un valor por referencia como strin23 el frame or! asi2nar"a null a ese par6metro y no se queBar"a. %ero int no acepta null, as" que el frame or! da ese error. 's normal, al principio, pensar que para solucionar esto bastar"a con aadir, un mGtodo 5ndex sin par6metros al controlador.

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

20

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com #l2o como7


public class HomeController : Controller { // =R<s tipo /Home/Index/;8 public ActionResult Index(int i) { return Vie ()! " // =R<s tipo /Home/Index public ActionResult Index() { return Vie ()! " "

%ero si probamos esto, nos damos cuenta de que ahora nos aparece otro error distinto7

#dem6s ese error aparece indistintamente, ya sea que entremos http788servidor8Fome85ndex8/0 1con id3 o http788servidor8Fome85ndex 1sin id3. La ra?n de este error es muy simple7 una misma accin slo puede ser implementada por un solo mGtodo 1hay una excepcin a este caso que es cuando se usan verbos http distintos, pero eso lo veremos en art"culos posteriores3. 'n este caso tenemos dos mGtodos 15ndex13 y 5ndex1int33 que ambos implementan la accin 5ndex. N eso no est6 permitido. La solucin a todo ^ese l"o_ pasa por hacer una de esas dos cosas7 /. +onvertir el par6metro de la accin a al2o que acepte nulls 1p.eB. strin2 o bien int93. 2. I modificar la tabla de rutas para que el par6metro en lu2ar de ser opcional, ten2a un valor por defecto. $i optamos por el primer caso, la accin puede quedar como7
public class HomeController : Controller { public ActionResult Index(intJ id) { return Vie ()! " "

#hora, la HDL http788servidor8Fome85ndex se enruta a esta accin y como el valor de ruta id no existe, el mGtodo de accin recibir6 un null. %or otro lado la HDL http788servidor8Fome85ndex8/0 se enruta a esta misma accin y el valor de ruta id valdr6 /0 1y ese ser6 el valor del par6metro que reciba el controlador3. $i optamos por modificar la tabla de rutas, en lu2ar de declarar el valor de ruta id como opcional, dicho valor debe tener un valor por defecto7
routes&0apRoute( (1e6ault(: // Route name ({controller"/{action"/{id"(: // =R< it* parameters ne {controller ' (Home(: action ' (Index(: id ' 8" // .arameter de6aults )!

-iBaos ahora que el valor por defecto del valor de ruta id es 0. #hora la HDL http788servidor8Fome85ndex se enruta a la accin con el valor de ruta id con valor 0. N por su lado la HDL http788servidor8Fome85ndex820 se enruta a la misma accin pero con el valor de ruta id a 20. Debe notarse que en este caso no puede diferenciarse entre la url http788servidor8Fome85ndex y la url http788servidor8Fome85ndex80 1ambas HDLs tienen el valor de ruta id con valor 03. #s" terminamos este art"culo dedicado a la tabla de rutas, uno de los componentes b6sicos de #$%.&'( )*+ pero que muy poca 2ente le presta atencin al principioQ

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

21

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com

Artculo por

Eduard Toms

-sando 6uerystrin* en ASP.NET MVC


En toda aplicacin web 'a) dos mecanismos b/sicos &ue se usan para pasar informacin de cliente al ser$idor0 usando la .,- 1lo &ue se conoce como &uer)strin!2 o usando un formulario 1lo &ue se conoce como P3ST2. #$%.&'( )*+ tiene un soporte directo para usar la querystrin27 los par6metros que se pon2an a la HDL ser6n enviados como par6metros de la accin correspondiente. 's decir, si yo ten2o la si2uiente url7 http788host8home85ndex9p/:/0>p2:no 1y suponiendo la tabla de rutas por defecto3, se invocar6 la accin 5ndex de Fome+ontroller con dos par6metros p/ 1con valor /03 y p2 con valor ^no_. #s" en el controlador podr"amos tener definida la accin de la si2uiente forma7
public ActionResult Index(int p;: strin% p+) { // Codi%o&&& "

Los nombres de los par6metros deben coincidir con los nombres de los par6metros de la querystrin2. Cien, fiBaos que dado que hemos declarado el par6metro p/ como int slo podemos pasar valores enteros, mientras que en el par6metro p2, podemos pasar cualquier cadena. $i pasamos una cadena en el par6metro p/, p.eB. la url http788host8home8index9 p/:texto>p2:otrotexto el error que recibimos es el si2uiente7

Lo que ha ocurrido es que #$%.&'( )*+ ha intentado convertir el valor de p/ 1^texto_3 a un entero. #l no poder hacerlo, internamente asi2na null al valor del par6metro p/, pero lue2o cuando debe invocar el mGtodo 5ndex y pasarle un int se encuentra que int no acepta valores null. De aqu" el error que recibimos. +omo podr"amos evitar esto9 Cueno@ una manera f6cil y sencilla es usar int9 1es decir &ullable3 en lu2ar de int para declarar el tipo de p/7
public ActionResult Index(intJ p;: strin% p+) { // Codi%o "

#hora si invocamos la url y el valor de p/ no es numGrico, nos lle2ar6 null, mientras que si el valor de p/ es numGrico recibiremos su valor. La re2la es realmente muy simple7 $i quieres que un par6metro de querystrin2 sea opcional debes usar un tipo por referencia

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

22

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com 1es decir una clase como strin2 o &ullable3. $i usas un tipo por valor 1como int o double3 el par6metro no puede ser opcional y adem6s el valor que se entre en la HDL debe ser convertible de cadena al tipo concreto que pon2as en el controlador.

7enerar -/#s con 6uerystrin*s desde las %istas


Hno de los errores m6s frecuentes en #$%.&'( )*+ es tener cdi2o en las vistas que sea parecido a este7
.ulsa )a *re6'(/Home/Vie Jpid';8(,aKuL)/a, para ?er los detalles

'ste cdi2o tiene dos errores fundamentales. /. 'st6 i2norando al tabla de rutas. 'st6 2enerando las HDLs usando la convencin de +ontrolador8#ccin pero esta convencin es slo v6lida si se usa la tabla de rutas est6ndar. 'n proyectos de tamao medio es normal tener una tabla de rutas que sea totalmente personali?ada 1Sesa es una de las 2racias de #$%.&'( )*+Q3 2. 'st6 pasando los par6metros siempre en querystrin2, i2norando los valores de ruta %ara solucionar el primer punto, lo que debemos hacer es usar el Felper Hrl. Los Felpers son clases que nos proporcionan mecanismos de ayuda 1de serie vienen al2unos que iremos viendo y se pueden crear de propios3, para ayudarnos con tareas repetitivas. %ara 2enerar una HDL que respete la tabla de rutas debemos usar el mGtodo Hrl.#ction. $u firma b6sica es Hrl.#ction 1^accin_, ^controlador_3. #s" el cdi2o anterior lo podemos reescribir de la forma7
.ulsa )a *re6'(#=rl&Action((Vie (:(Home()Jpid';8(,aKuL)/a, para ?er los detalles

$i eBecutamos eso y miramos el cdi2o F()L veremos que es exactamente lo que hab"amos tecleado antes 1debido a que usamos la tabla de rutas est6ndar3. %ero si aado una entrada a la tabla de rutas, deB6ndola as"7
routes&I%noreRoute(({resource"&axd/{Hpat*In6o"()! routes&0apRoute( (Ver(: (Ver.roducto(: ne {controller ' (Home(: action ' (Vie (")! routes&0apRoute( (1e6ault(: // Route name ({controller"/{action"/{id"(: // =R< it* parameters ne { controller ' (Home(: action ' (Index(: id ' =rl.arameter&Iptional " // .arameter de6aults )!

#hora la HDL que se me 2enera usando Hrl.#ction es la si2uiente7


.ulsa )a *re6'(/Ver.roductoJpid';8(,aKuL)/a, para ?er los detalles

#s" pues, siempre que necesitGis obtener una HDL desde una vista, usad Hrl.#ction@ recordad que el formato real de las HDLs depende de la tabla de rutas. #sumir que siempre estar6n en la forma 8controlador8accin es una muy mala pr6ctica 1y como dec"a antes, un error comEn al principio3.

Par8metros 6uerystrin* y route %alues


*amos a ver ahora que si2nifica el se2undo de los errores que comet"amos 1pasar los valores siempre en querystrin2 i2norando los valores de ruta3. %ara evitar entrar demasiado en tecnicismos dirG que #$%.&'( )*+ me?cla todos los par6metros que le lle2an antes de pasarlos a los controladores. # un controlador le pueden lle2ar par6metros por tres formas b6sicas 1vale, eso no es del todo cierto, hay m6s formas pero vamos a i2norarlas de momento37 como par6metros de ruta, como querystrin2 y como %I$( 1de esos hablaremos en un art"culo posterior3. Los par6metros de ruta son los que colocamos en la HDL separados por la barra, es decir7 http788host8controlador8accion8/0. 'n este caso /0 es el valor de un par6metro de ruta. LDe cu6l9 %ues el nombre debe estar explicitado en la tabla de rutas. *amos a suponer que usamos la tabla de rutas est6ndar. 'n este caso el nombre de dicho par6metro es id. #hora yo os pre2unto@ que ocurrir"a si usamos la HDL http788host8controlador8accion8/09id:20 9 -iBaos que la cuestin no es balad"7 a nuestro controlador le estamos pasando7 Hn par6metro de ruta con valor /0 y que 12racias a la tabla de rutas3 se llama id Hn par6metro de querystrin2 llamado id con valor 20.

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

23

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com #mbos par6metros 1de ruta y querystrin23 se mapean a par6metros de la accin del controlador. L#s" pues@ que valor recibiremos en el par6metro id de nuestra accin9 LI bien #$%.&'( )*+ 2enerar6 un error9 %ues lo que recibiremos en nuestra accin ser6 el valor del par6metro de ruta 1es decir /0, en lu2ar de 2037

-iBaos en la HDL entrada 18Fome85ndex8/09id:203 y como el valor del par6metro id es ^/0_ y no ^20_. 'so es debido a que coment6bamos antes7 #$%.&'( )*+ me?cla todos los par6metros que le lle2an antes de enla?arlos con los controladores y lo hace se2En una cierta prioridad. N los par6metros de ruta 1cuyo nombre se define en la tabla de rutas3 tienen m6s prioridad. 'so deber"a tenerlo en cuenta cuando 2enero HDLs, es decir, en este caso deber"a 2enerar HDLs usando la convencin 8controlador8accin8valoraid antes que 8controlador8accin9id:valoraid #l final eso nos implica que no deber"amos nunca 2enerar las HDLs con par6metros querystrin2 aadidos a mano. %or suerte para nosotros el helper Hrl.#ction que hemos visto antes viene de nuevo a nuestra ayuda. 'n una de sus sobrecar2as Hrl.#ction acepta un obBeto annimo cuyas propiedades son los valores a mandar al controlador. SHrl.#ction es lo suficientemente inteli2ente como para usar valores de ruta si est6n definidos y querystrin2 en caso de que noQ #s" pues si tenemos la tabla de rutas est6ndar y tenemos las si2uientes llamadas a Hrl.#ction7 Hrl /7 VHrl.#ction1J5ndexJ, JFomeJ, ne [ id : 20 \3 Hrl 27 VHrl.#ction1J5ndexJ, JFomeJ, ne [ id : 20, otroaid:,0\3 Hrl ,7 VHrl.#ction1J5ndexJ, JFomeJ, ne [otroaid:,0\3 La respuesta 2enerada por esa vista es la si2uiente7 Hrl /7 8Fome85ndex820 Hrl 27 8Fome85ndex8209otroaid:,0 Hrl ,7 89otroaid:,0 L&o es una maravilla9 Hrl.#ction sabe que id es un par6metro de ruta y nos lo coloca como tal. N sabe que otroaid no lo es y nos lo coloca usando queryastrin2. 'n este caso la accin en el controlador la tenemos definida7
public ActionResult Index(strin% id: strin% otroFid) { return Vie ()! "

-iBaos como desde el controlador recibimos de i2ual manera par6metros de ruta que par6metros que ven2an por querystrin2@ 73 'n el si2uiente art"culo del tutorial vamos a ver como mandar datos de formularios a las vistas, es decir cmo usar %I$(.
Artculo por

Eduard Toms

-so de P9ST en ASP.NET MVC


Sin duda al!una de todos los mecanismos &ue 'a) para mandar informacin desde una $ista 'acia un

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

24

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com controlador, el uso de P3ST es el m/s com4n. Dicho r6pido y mal7 el uso de %I$( equivale al uso de formularios F()L. Di2o lo de mal porque ni los formularios son la Enica manera de enviar datos v"a %I$(, ni todos los formularios se env"an por %I$(, pero no nos vamos a centrar en estos detalles, ya que la mayor"a de formularios hoy en d"a se env"an via %I$(. La principal diferencia entre enviar datos via %I$( o via ]'( 1es decir usando la HDL, ya sea a travGs de querystrin2 que vimos en el art"culo anterior, o en valores de ruta3 es que con %I$( los datos circulan en el cuerpo de la peticin y no son visibles en la HDL.

En%iar datos a tra%&s de un .ormulario


Fablar de datos enviados a travGs de un formulario a un controlador implica presentar una caracter"stica de #$%.&'( )*+ que se va a convertir en un 2ran aliado7 el model bindin2. %or ese nombre nos referimos a la capacidad de #$%.&'( )*+ de construir obBetos a partir de los datos que le lle2uen en la peticin. %ara ser honestos el model bindin2 funciona con independencia de si los datos vienen de un formulario, en la querystrin2 o por valores de ruta, pero va a ser cuando se mandan datos a travGs de formularios que adquiere su m6xima expresin. %ero vayamos por partes... 'mpecemos por una vista sencilla, que se mostrar6 en respuesta a la accin &uevo del controlador Hsuarios7
)*+,/ue?o usuario)/*+, )6orm met*od'(.I-T(, )label 6or'(lo%in(,lo%in:)/label, )input t5pe'(text( name'(lo%in( /, )br /, )label 6or'(pass ord(,cla?e:)/label, )input t5pe'(text( name'(pass ord( /, )br /, )input t5pe'(submit( ?alue'(en?iar(/, )/6orm,

'sta vista crea un formulario que ser6 enviado por %I$(. 'l formulario contiene7 Dos etiquetas con texto 13 Dos campos de texto 1Xinput type:_text_Z3, uno que se llama ^lo2in_ y otro llamado ^pass ord_ 1el valor de sus atributos name3. Hn botn para enviar el formulario

$i os fiB6is no hemos indicado a que HDL debe enviarse el formulario. 'so se hace a travGs del atributo action de la etiqueta XformZ. $i no aparece, el formulario se mandar6 de vuelta a la misma HDL a la que estamos. 'n el controlador 1Hsuarios+ontroller3 metemos simplemente una accin que muestre la vista7
public ActionResult /ue?o() { return Vie ()! "

Cien, si ahora con el nave2ador nos diri2imos a 8Hsuarios8&uevo nos aparecer6 la vista con el formulario. %odemos rellenar datos y pulsar enviar. #l pulsar enviar simplemente se nos mostrar6 la vista 1vac"a3 de nuevo. 'sto ocurre porque al pulsar el botn de enviar datos se env"a el formulario a la misma HDL 18Hsuarios8&uevo3 de la que venimos. %or lo tanto se invoca de nuevo la accin &uevo del controlador Hsuarios que lo Enico que hace es mostrar la vista otra ve?. #hora bien, lo que nosotros queremos es que cuando se env"e el formulario v"a %I$( podamos obtener los datos y hacer al2o con ellos. 'n definitiva queremos hacer otra cosa que no sea mostrar la vista. La verdad es que suena un poco como si quisiGramos otra accin distinta. %ero, si record6is en los inicios de este manual, diBimos que una accin slo pod"a estar implementada por un solo mGtodo en el controlador. Cueno, la verdad es que... mentimos un poquillo. La realidad es que una accin puede estar implementada por un solo mGtodo por cada verbo F((%. $i no sabes lo que son los verbos F((% no te preocupes mucho7 es la manera tGcnica de referirnos a ]'( y %I$(. #s" ]'( es un verbo F((% y %I$( es otro. Fay m6s, como F'#D, %H( y D'L'(' pero dado que no hay soporte en F()L para estos verbos no nos vamos a preocupar de ellos 1eso no si2nifica que #$%.&'( )*+ no los soporte, slo que no vamos a verlo aqu"3. %ara nosotros slo van a existir ]'( y %I$(. N volviendo a lo que dec"amos, eso si2nifica que para la misma accin 1por lo tanto, la misma

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

25

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com HDL3 puedo tener dos mGtodos en el controlador7 uno que se invoque a travGs de ]'( y otro que se invoque a travGs de %I$(. #s" pues podemos aadir el si2uiente mGtodo a nuestro controlador7
2Http.ost3 public ActionResult /ue?o(strin% lo%in: strin% pass ord) { // Codi%o&&& "

Ibservad como el mGtodo est6 decorado con TFttp%ostU. #l aplicar este atributo al mGtodo le estamos indicando a #$%.&'( )*+ que cuando se deba invocar la accin &uevo del controlador Hsuarios use este mGtodo si la invocacin es v"a %I$(. $i la invocacin es v"a ]'( 1p.eB. tecleando la HDL en la barra de direcciones del nave2ador3 se invocar6 el mGtodo &uevo que ya ten"amos. -iBaos pues que tenemos una manera simple y ele2ante de separar nuestro cdi2o en funcin del verbo F((% que se use. -iBGmonos ahora en los par6metros del mGtodo &uevo7 dos par6metros cuyo nombre es el mismo que los nombres de los campos del formulario. $lo con esto le basta a #$%.&'( )*+ para enla?ar los valores del formulario con los par6metros de la accin del controlador. #hora bien, ima2ina que nuestro formulario en lu2ar de tener dos campos, tiene veinte... L(e ima2inas tener que poner veinte par6metros en la accin del controlador9 %ues para evitar esto existe precisamente el model bindin2.

Model +indin*
Llamamos model bindin2 a la capacidad de #$%.&'( )*+ de crear obBetos 1de clases nuestras3 a partir de los par6metros que ven2an en la peticin. 'n nuestro caso a partir de los campos del formulario que enviamos. #s" podr"amos tener una clase Hsuario tal y como si2ue7
public class =suario { public strin% lo%in { %et! set! " public strin% pass ord { %et! set! " "

N sustituir los dos par6metros que ten"amos en la accin &uevo por un solo par6metro de tipo Hsuario7
2Http.ost3 public ActionResult /ue?o(=suario usuario) { // Codi%o&&& "

N 2racias al poder del model bindin2 recibiremos un obBeto usuario rellenado a partir de los datos del formulario. La Enica condicin es que las propiedades del obBeto se llamen i2ual que los campos del formulario. Lle2ados a este punto podr"amos validar los datos y si hay al2En error, los podemos mandar de vuelta a la vista 1Bunto con un mensaBe explicativo del error37
2Http.ost3 public ActionResult /ue?o(=suario usuario) { i6 (strin%&Is/ullIrEmpt5(usuario&lo%in) MM strin%&Is/ullIrEmpt5(usuario&pass ord)) { Vie $a%&Error ' (<o%in o pass ord no pueden estar ?acLos(! return Vie (usuario)! " // 1amos de alta el usuario en la $$11 5 redireccionamos return RedirectToAction((Home(: (Index()! "

$i el campo de lo2in o pass ord se deBa vacio, entonces aadimos un campo llamado 'rror en el *ie Ca2 y devolvemos la vista, pas6ndole como datos el obBeto usuario que hemos recibido. $i por otro lado la validacin es correcta rediri2imos el usuario a la accin 5ndex del controlador Fome. Cien, ahora vayamos a por la vista7 la idea es que si la vista recibe un obBeto de tipo Hsuario rellene los campos de texto con el valor de los campos de dicho usuario. De este modo al mandarle de vuelta el obBeto desde el controlador, el usuario ver6

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

26

Tu mejor ayuda para aprender a hacer webs www.desarrolloweb.com exactamente lo mismo que Gl ha enviado y slo deber6 corre2ir los errores que se le indiquen. 'l nuevo cdi2o de la vista es7
#model 0?c1atos.ost&0odels&=suario )*+,/ue?o usuario)/*+, #i6 (Nstrin%&Is/ullIrEmpt5(Vie $a%&Error)) { )di? class'(error(,#Vie $a%&Error)/di?, " )6orm met*od'(.I-T(, )label 6or'(lo%in( ,lo%in:)/label, )input t5pe'(text( name'(lo%in( ?alue'(#(0odelN'null J 0odel&lo%in : strin%&Empt5)(/, )br /, )label 6or'(pass ord(,cla?e:)/label, )input t5pe'(text( name'(pass ord( /, )br /, )input t5pe'(submit( ?alue'(en?iar(/, )/6orm,

Lo que hemos aadido respecto a la vista ori2inal es que muestre un XdivZ con el error en caso de que este exista y establecer el valor del atributo value del campo lo2in al valor del elemento recibido si existe. 'l valor del campo pass ord no lo enla?amos porque, por norma 2eneral, cuando hay un error se obli2a siempre a volver entrar el pass ord. SN listosQ $i el usuario env"a un formulario con el campo lo2in o pass ord vac"os, se le mostrar6 de nuevo los datos que hab"a entrada 1salvo el pass ord3 Bunto con el mensaBe de error. L$encillo, verdad9 %ues bien, esa manera en que hemos hecho la validacin, y la forma en como hemos modificado la vista para mostrar los datos devueltos por el controlador, aunque funcionan no son las ideales. 'n los prximos art"culos veremos dos maneras m6s ele2antes de hacerlo7 por un lado la validacin mediante Data #nnotations y por otro el uso de los helpers en las vistas... SHn saludoQ
Artculo por

Eduard Toms

Manual del framework ASP.NET MVC: www.desarrolloweb.com manuales framework!asp!ne"!m#c.h"ml


" #os manuales de DesarrolloWeb.com tienen el copyright de sus autores. $o reproducir sin autorizaci%n.

27

También podría gustarte