CSharp – ASP.net en La Practica

  • ASP.NET en la prcticaEn este ltimo captulo dedicado a ASP.NET, trataremos algunosaspectos de inters a la horade construir aplicaciones reales.Despus de haber visto en qu consiste una aplicacines web,cmo secrean formularios web en ASP.NET y de qu forma se pueden realizarlas tareas mscomunes con las que debe enfrentarse el programador deaplicaciones web, ahoracomentaremos algunos de los aspectosrelativos a la organizacin interna de las aplicacionesweb:- En primer lugar, comentaremos brevemente algunos de lospatrones de diseo quese suelen emplear a la hora de crear laaplicacin web con el objetivo de que stamantenga su flexibilidad ysu mantenimiento no resulte tedioso.- A continuacin, nos centraremos en los mecanismos existentesque nos facilitanque el aspecto externo de una aplicacin webASP.NET sea homogneo.- Una vez descritos los principios en los que se suelen basarlas aplicaciones webbien diseadas, repasaremos cmo se puede hacerque el contenido de nuestrainterfaz web cambie dinmicamenteutilizando un mecanismo conocido comoenlace de datos [databinding].- Finalmente, cerraremos este captulo centrndonos en laconstruccin deformularios de manipulacin de datos, como ejemplo mscomn del tipo demdulos que tendremos que implementar en cualquieraplicacin.
  • ASP.NET en la prcticaOrganizacin de la interfaz deusuario…………………………125Componentes de la interfaz ……………………………..125El modelo MVC en ASP.NET …………………………127Controladores en ASP.NET……………………………129Control de laaplicacin…………………………………… 135Aspecto visual de la aplicacin…………………………………..140Filtros con mdulos HTTP………………………………. 142La directiva #include……………………………………….143Plantillas………………………………………………………..145Configuracin dinmica de laaplicacin……………………..147Listas de opciones…………………………………………. 149Vectores simples: Array y ArrayList…………………150Pares clave-valor: Hashtable y SortedList……….. 151FicherosXML ……………………………………………… 153Conjuntos de datos………………………………………… 157El controlasp:Repeater ………………………………… 158El controlasp:DataList………………………………….. 161El controlasp:DataGrid ………………………………… 163Formularios de manipulacin dedatos………………………..170Edicin de datos……………………………………………. 170Formulariosmaestro-detalle en ASP.NET…………. 174124 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • Organizacin de la interfaz de usuarioComo Steve McConnell expone en su libro Software ProjectSurvival Guide, la mayor partedel trabajo que determina el xito oel fracaso final de un proyecto de desarrollo de softwarese realizaantes de que comience su implementacin: «si el equipo investiga losrequisitos afondo, desarrolla el diseo con detalle, crea una buenaarquitectura, prepara un plan deentrega por etapas y controla loscambios eficazmente, la construccin [del software]destacar por sufirme progreso y la falta de problemas graves». Obviamente, lalista decondiciones que se han de cumplir para que un proyecto dedesarrollo de software finalice conxito es extensa, como no podaser menos dada la complejidad de las tareas que handerealizarse.En los primeros apartados de este captulo nos centraremos en unade las bases que sirven deapoyo al xito final del proyecto: lacreacin de una buena arquitectura. En concreto, veremoscmo sepueden organizar los distintos elementos que pueden formar parte dela interfaz webde una aplicacin realizada con ASP.NET.Componentes de la interfazLa primera tentacin de un programadorde aplicaciones web consiste en escribir todo elcdigo de suaplicacin en la propia pgina ASP.NET. Sin embargo, en cuanto laaplicacincomienza a crecer, empiezan a aparecer cierta redundancia.La existencia de fragmentos decdigo duplicados complicarn elmantenimiento de la aplicacin y la realizacin denuevasmejoras.Cuando situaciones como esta se presentan, lo usuales encapsular la lgica de la aplicacinen componentesindependientes. La redundancia se elimina a cambio de un incrementoen lacomplejidad de la aplicacin. Cuanto ms compleja sea laaplicacin, ms difcil ser queotros programadores sean capaces deentender correctamente su funcionamiento. Por tanto, lacomplejidadintroducida tambin dificulta el mantenimiento de la aplicacin,aunque sea enun sentido totalmente diferente al causado por laexistencia de cdigo duplicado.Afortunadamente, existen soluciones bien conocidas que consiguendotar a las aplicaciones decierta flexibilidad sin incrementarexcesivamente su complejidad. En el caso del desarrollodeinterfaces de usuario, la solucin ms conocida es el patrn dediseo MVC[Model-View-Controller], en el que se distinguen trescomponentes bien diferenciados:- El modelo encapsula el comportamiento y los datoscorrespondientes al dominiode la aplicacin. Habitualmente seconstruye un modelo de clases del problemacon el que se esttrabajando, independientemente de cmo se vayan a presentarlos datosde cara al usuario.125ASP.NET en la prcticahttp://csharp.ikor.org/
  • – Las vistas consultan el estado del modelo para mostrrselo alusuario. Porejemplo, un mismo conjunto de datos puede verse enforma de tabla ogrficamente, en una pantalla o en un informeimpreso. Cada una de las formas demostrar los constituye una vistaindependiente y, en vez de tener en cada vista elcdigo necesariopara acceder directamente a los datos, cada una de las vistasdelegaen el modelo, que es el responsable de obtener los datos y realizarlosclculos necesarios.- Los controladores, por ltimo, son los encargados de permitirque el usuariorealice acciones. Dichas acciones se traducirn en lasrespuestas que resultenapropiadas, las cuales pueden involucrarsimplemente a las vistas o incluir larealizacin de operacionessobre el modelo.El modelo MVC: Las vistas y los controladores dependen delmodelo, peroel modelo no depende ni de la vista ni del controlador.Esto permite que elmodelo se pueda construir y probarindependientemente de la presentacinvisual de la aplicacin. Adems, se pueden mostrar varias vistasde losmismos datos simultneamente.El modelo MVC ayuda a modularizar correctamente una aplicacin enla cual el usuariomanipula datos a travs de una interfaz. Si elusuario puede trabajar con los mismos datos dedistintas formas, lohabitual es encapsular el cdigo compartido en un mdulo aparte conelfin de evitar la existencia de cdigo duplicado. Se puede decirque el modelo contiene elcomportamiento comn a las distintas formasque tiene el usuario de manipular los datos. Dehecho, la existenciade un modelo independiente facilita enormemente la construccindesistemas que han de ofrecer varios interfaces. Este sera el casode una empresa que deseadisponer de una aplicacin Windows para usointerno de sus empleados, una interfaz webpara que sus clientespuedan realizar pedidos y un conjunto de servicios web parafacilitar elintercambio de datos con sus proveedores.126 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • De hecho, aunque el usuario trabaje con los datos de una nicaforma, el cdigocorrespondiente a la interfaz suele cambiar msfrecuentemente que el cdigo correspondientea la lgica de laaplicacin. Por ejemplo, es bastante habitual cambiar el aspectovisual de unaaplicacin manteniendo su funcionalidad intacta. Esosucede cada vez que ha de adaptarse lainterfaz a un nuevodispositivo, como puede ser un PDA cuya resolucin es muchomslimitada que la de un monitor convencional.En el caso de las aplicaciones web, los conocimientos necesariospara crear la interfaz (enHTML dinmico por lo general) suelen serdiferentes de los necesarios para implementar lalgica de laaplicacin (para la que se utilizan lenguajes de programacin de altonivel). Porconsiguiente, la separacin de la interfaz y de la lgicade la aplicacin facilita la divisin deltrabajo en un equipo dedesarrollo.Por otro lado, cualquier modificacin requerir comprobarque los cambios realizados no hanintroducido errores en elfuncionamiento de la aplicacin. En este sentido, mantenerlosdistintas partes de una aplicacin lo menos acopladas posiblesiempre es una buena idea.Adems, comprobar el funcionamiento de lainterfaz de usuario es mucho ms complejo ycostoso que realizarpruebas de unidad sobre mdulos independientes (algo quedescribiremosen la ltima parte de este libro cuando veamos el usode NUnit para realizar pruebas deunidad).Una de las decisiones de diseo fundamentales en laconstruccin desoftware es aislar la interfaz de la lgica de laaplicacin. Al fin yal cabo, el xito del modelo MVC radicaen esa decisin: separar lalgica de la aplicacin de la lgicacorrespondiente a supresentacin.En los dos prximos apartados veremos cmo se utiliza el modeloMVC en ASP.NET y cmose pueden crear controladores que realicentareas comunes de forma uniforme a lo largo yancho de nuestrasaplicaciones.El modelo MVC en ASP.NETLas aplicaciones web utilizan una variante del modelo MVCconocida como MVC pasivoporque las vistas slo se actualizan cuandose realiza alguna accin a travs del controlador.Esto es, aunque elestado del modelo se vea modificado, la vista no seactualizarautomticamente. El navegador del usuario muestra la vistay responde a las acciones delusuario pero no detecta los cambiosque se puedan producir en el servidor. Dichos cambiospuedenproducirse cuando varios usuarios utilizan concurrentemente unaaplicacin o existenotros actores que pueden modificar los datos conlos que trabaja nuestra aplicacin. Laspeculiaridades de losinterfaces web hacen que, cuando es necesario reflejar en elnavegadordel usuario los cambios que se producen en el servidor,tengamos que recurrir a estrategiascomo las descritas al estudiarel protocolo HTTP en el apartado «cuestin de refresco» del127ASP.NET en la prcticahttp://csharp.ikor.org/
  • captulo anterior.Cuando comenzamos a ver en qu consistan las pginas ASP.NET,vimos que existen dosestilos para la confeccin de pginasASP.NET:- Podemos incluir todo en un nico fichero .aspx o podemosseparar los controlesde la interfaz del cdigo de la aplicacin. Siempleamos un nico fichero .aspx,dicho fichero implementa los tresroles diferenciados por el modelo MVC:modelo, vista y controladoraparecen todos revueltos. Entre otros inconvenientes,esto ocasionaque un error introducido en el cdigo al modificar el aspectovisualde una pgina no se detectar hasta que la pgina se ejecute denuevo.- Si empleamos ficheros diferentes, se separan fsicamente lainterfaz y la lgica dela aplicacin. El fichero .aspx contendr lapresentacin de la pgina (la vistasegn el modelo MVC) mientras queel fichero .aspx.cs combinar el modelocon el controlador. El cdigocomn a distintas pginas se podr reutilizar concomodidad y un cambioque afecte a la funcionalidad comn no requerir quehaya que irmodificando cada una de las pginas. Adems, se podr modificarelaspecto visual de la pgina sin temor a introducir errores en elcdigo de laaplicacin y podremos utilizar todas las facilidades quenos ofrezca el entorno dedesarrollo para desarrollar ese cdigo (alcontener el fichero .aspx.cs una claseconvencional escrita enC#).Hasta aqu, nada nuevo: el cdigo se escribe en un fichero apartepara facilitar nuestro trabajo(algo que hicimos desde el primermomento). Sin embargo, no estamos utilizando ningn tipodeencapsulacin.Por un lado, se hace referencia a las variables de instancia dela clase desde el fichero .aspx.Por ejemplo, podemos tener un botnen nuestra pgina ASP.NET:Dicho botn, representado por medio de la etiqueta asp:button,hace referencia a unavariable de instancia declarada en el fichero.aspx.cs:protected System.Web.UI.WebControls.Button button;Por otro lado, el mtodo InitializeComponent define elfuncionamiento de la pgina alenlazar los controles de la pgina conel cdigo correspondiente a los distintos eventos:private void InitializeComponent()128 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • {this.button.Click += newSystem.EventHandler(this.Btn_Click);this.Load += newSystem.EventHandler(this.Page_Load);}Si bien siempre es recomendable separar la interfaz del cdigo,la vista delmodelo/controlador, esta separacin es insuficientecuando tenemos que desarrollaraplicaciones reales. Tcnicamente,sera posible reutilizar el cdigo del fichero .aspx.cs,aunque esoslo conducira a incrementar el acoplamiento de otras partes de laaplicacin conla pgina ASP.NET. Para evitarlo, se crean clasesadicionales que separan el modelo delcontrolador. El controladorcontendr nicamente el cdigo necesario para que el usuariopuedamanejar la pgina ASP.NET y el modelo ser independiente por completode la pginaASP.NET.En la ltima parte de este libro veremos cmo se crea dicho modeloy cmo, al serindependiente, se pueden desarrollar pruebas de unidadque verifican su correctofuncionamiento. De hecho, tener la lgicade la aplicacin separada por completo de lainterfaz es algonecesario para poder realizar cmodamente pruebas que verifiquenelcomportamiento de la aplicacin. En las aplicaciones web,comprobar el funcionamiento lalgica incluida en una pgina resultaespecialmente tedioso, ya que hay que analizar eldocumento HTML quese obtiene como resultado. Separar la lgica de la aplicacinnosfacilita enormemente el trabajo e incluso nos permiteautomatizarlo con herramientas comoNUnit, que tambin se ver en laltima parte de este libro.Por ahora, nos centraremos en cmo se puede implementar elcontrolador de una aplicacinweb desarrollada en ASP.NET.:Controladores en ASP.NETEn el modelo MVC, la separacin bsica es la que independiza elmodelo de la interfaz de laaplicacin. La separacin entre vistas ycontroladores es, hasta cierto punto, secundaria. Dehecho, en lamayor parte de entornos de programacin visual, vistas ycontroladores seimplementan conjuntamente, a pesar de ser unaestrategia poco recomendable. En el caso delas aplicaciones web, noobstante, la separacin entre modelo y controlador est muybiendefinida: la vista corresponde al HTML que se muestra en elnavegador del usuario mientrasque el controlador se encarga en elservidor de gestionar las solicitudes HTTP. Adems, enuna aplicacinweb, distintas acciones del usuario pueden conducir a la realizacindedistintas tareas (responsabilidad del controlador) aun cuandoconcluyan en la presentacin dela misma pgina (la vista en el modeloMVC).En el caso de las aplicaciones web, existen dos estrategiaspara implementar la partecorrespondiente al controlador definidopor el modelo MVC, las cuales dan lugar a dos tiposdecontroladores: los controladores de pgina (especficos para cada unade las pginas de laaplicacin web) y los controladores de aplicacin(cuando un controlador se encarga de todaslas pginas de laaplicacin).129ASP.NET en la prcticahttp://csharp.ikor.org/
  • Controladores de pginaUsualmente, se utiliza un controlador independiente para cadapgina de la aplicacin web. Elcontrolador se encarga de recibir lasolicitud de pgina del cliente, realizar lasaccionescorrespondientes sobre el modelo y determinar cul es lapgina que se le ha de mostrar alusuario a continuacin.En el caso de ASP.NET y de muchas otras plataformas para eldesarrollo de aplicaciones web,como JSP o PHP, la plataforma nosproporciona los controladores de pgina, usualmentemezclados con lavista a la que corresponde la pgina. En ASP.NET, los controladorestomanforma de clase encargada de gestionar los eventos recibidospor la pgina .aspx. Estaestrategia nos facilita el trabajo porque,en cada momento, slo tenemos que preocuparnos dela accin con la quese ha de responder a un evento concreto. De esta forma, lacomplejidaddel controlador puede ser reducida y, dada la dificultadque conlleva probar el funcionamientode una interfaz web, lasimplicidad siempre es una buena noticia.Usualmente, las aplicaciones web realizan algunas tareas fijaspara todas las solicitudesrecibidas, como puede ser laautentificacin de usuarios que ya se trat en el captulo anterior.Dehecho, tener un controlador para cada pgina (y, veces, por accindel usuario) sueleconducir a la aparicin de bastante cdigoduplicado. Cuando esto sucede, se suele crear unaclase base queimplemente las funciones comunes a todos los controladores y de laquehereden los controladores de cada una de las pginas de laaplicacin. Otra opcin consiste encrear clases auxiliares queimplementen utilidades de uso comn. Este caso deberemosacordarnossiempre de invocar a esas utilidades en todas y cada una de laspginas de laaplicacin, mientras que si utilizamos herencia podemosdotar a todos nuestros controladoresde cierta funcionalidad deforma automtica. Cuando la complejidad de esasoperacionesauxiliares es destacable, conviene combinar las dosestrategias para mantener la cohesin delos mdulos de la aplicacin yfacilitar su mantenimiento. Esto es, se puede utilizar unajerarquade clases para los controladores y que algn miembro de estajerarqua(presumiblemente cerca de su base) delegue en clasesauxiliares para realizar las tareasconcretas que resultennecesarias.Cabecera comn para distintas pginas ASP.NETEn ocasiones, hay quemostrar informacin de forma dinmica en una cabecera comn paratodaslas pginas de una aplicacin (por ejemplo, la direccin de correoelectrnico delusuario que est actualmente conectado). En vez deduplicar el cdigo correspondiente a lacabecera en las distintaspginas, podemos hacer que la clase base muestre la parte comn ylassubclases se encarguen del contenido que les es especfico. EnASP.NET podemos crearuna relacin de herencia entre pginas yutilizar un mtodo genrico definido en la clasebase que serimplementado de forma diferente en cada subclase.En primer lugar, creamos la pgina ASP.NET que servir de base:BasePage.cs. Endicha clase incluiremos un mtodo virtual yrealizaremos las tareas que sean comunes paralas distintaspginas:130 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • Cabecera comn para distintas pginas ASP.NETpublic class BasePage : System.Web.UI.Page{…virtual protected void PageLoadEvent(object sender,System.EventArgs e) {}protected void Page_Load (object sender, System.EventArgs e){if(!IsPostBack) {eMailLabel.Text = «[email protected]»;PageLoadEvent(sender,e);}}…}Tambin se debe crear el fichero que contendr la parte comn delaspecto visual de laspginas: BasePage.inc.Hola,usuarioA continuacin, se crean las distintas pginas de la aplicacin. Enlos ficheros .aspx hayque incluir la directiva #include en el lugardonde queremos que aparezca la cabecera:……Por ltimo, al implementar la lgica asociada a los controladoresde las pginas, seimplementa el mtodo LoadPageEvent particular paracada pgina sin redefinir elmtodo Page_Load que ya se defini en laclase base:public class ApplicationPage : BasePage{…protected override void PageLoadEvent(object sender,System.EventArgs e) …}131ASP.NET en la prcticahttp://csharp.ikor.org/
  • Controladores de aplicacinEn la mayora de las aplicaciones web convencionales, las pginasse generan de formadinmica pero la navegacin entre las pginas esrelativamente esttica. En ocasiones, noobstante, la navegacin entrelas distintas partes de la aplicacin es dinmica. Por ejemplo,lospermisos del usuario o de un conjunto de reglas de configuracinpodran modificar el «mapade navegacin» de la aplicacin. En esecaso, la implementacin de los controladores depgina comienza acomplicarse: aparecen expresiones lgicas complejas para determinarelflujo de la navegacin. Por otro lado, puede que nuestra aplicacinincluya distintos tipos depginas, cada uno con sus peculiaridades.Cuantas ms variantes haya, ms niveles hay queincluir en la jerarquade clases correspondiente a los controladores. Fuera de control,lajerarqua de controladores puede llegar a ser inmanejable.Ensituaciones como las descritas en el prrafo anterior, resultarecomendable centralizar elcontrol de la aplicacin en uncontrolador nico que se encargue de tramitar todas lassolicitudesque recibe la aplicacin web. Un controlador de aplicacin, llamadousualmentefront controller, suele implementarse en dos partes:- Por un lado, un manejador [handler] es el que recibe laspeticiones. En funcin dela peticin y de la configuracin de laaplicacin (que podra almacenarse en unsencillo fichero XML), elmanejador ejecuta la accin adecuada y elige la pginaque se lemostrar al usuario a continuacin.- Por otro lado, el conjunto de acciones que puede realizar laaplicacin se modelamediante una jerarqua de comandos, utilizando lamisma filosofa que permiteimplementar las operaciones derehacer/deshacer en muchas aplicaciones. Todoslos comandosimplementan una interfaz unificada y cada uno de ellosrepresentauna de las acciones que se pueden realizar.Aparte de facilitar la creacin de aplicaciones web realmentedinmicas, usar un controladorcentralizado para una aplicacin tambinrepercute en otros aspectos del desarrollo de laaplicacin. Ya se hamencionado que comprobar el correcto funcionamiento de unainterfazde usuario requiere mucho esfuerzo. Lo mismo se puede decirde la lgica asociada a loscontroladores de pgina de una aplicacinweb. Al usar un controlador genrico eimplementar las acciones de laaplicacin como comandos independientes tambinfacilitamos la fase depruebas de la aplicacin.Respecto a los controladores de pgina, el uso extensivo dejerarquas de herencia conduce aaplicaciones cuyo diseo es frgilante la posibilidad de que se tengan que realizar cambios enlaaplicacin. Adems, determinadas funciones es mejor implementarlas deformacentralizada para evitar posibles omisiones. Piense, porejemplo, en lo que podra suceder sien una pgina de una aplicacin decomercio electrnico se le olvidase realizar alguna tareade controlde acceso. La centralizacin ayuda a la hora de mejorar laconsistencia de unaaplicacin.132 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • Controlador comn para distintas pginas ASP.NETSupongamos quepartimos de una aplicacin similar a la descrita en el ejemplo de laseccinanterior («cabecera comn para distintas pginas ASP.NET). Elmtodo Page_Load de laclase base BasePage se llama siempre que seaccede a una pgina. Supongamos ahora queel formato de la cabeceramostrada dependa de la solicitud concreta, su URL o susparmetros.En funcin de la solicitud, no slo cambiar la cabecera, sino elprocesonecesario para rellenarla. Esto podra suceder si nuestraaplicacin web sirve de base paradar soporte a varios clientes, paralos cuales hemos personalizado nuestra aplicacin. Laspginasindividuales seguirn siendo comunes para los usuarios, pero laparte implementadaen la clase base variar en funcin del casoparticular, por lo que se complica laimplementacin de BasePage:protected void Page_Load (object sender, System.EventArgse){string estilo;if (!IsPostBack) {estilo = Request[«style»];if ( estilo!=null && estilo.Equals(«vip»))… // SloVIPselse… // ConvencionalPageLoadEvent(sender, e);}}Conforme se aaden casos particulares, el desastre se va haciendoms evidente. Cualquiercambio mal realizado puede afectar aaplicaciones que estaban funcionando correctamente,sin causaaparente desde el punto de vista de nuestros enojados clientes.Paracrear un controlador de aplicacin que elimine los problemas demantenimiento a losque podra conducir una situacin como ladescrita, lo primero que hemos de hacer es crearun manejador quereciba las peticiones. En ASP.NET podemos utilizar la interfaz abajonivel IHttpHandler tal como pusimos de manifiesto en el captuloanterior al estudiar losmanejadores y filtros HTTP:using System;using System.Web;public class Handler : IHttpHandler{public void ProcessRequest(HttpContext context){Command command =CommandFactory.Create(context);command.Do (context);}133ASP.NET en la prcticahttp://csharp.ikor.org/
  • Controlador comn para distintas pginas ASP.NETpublic bool IsReusable{get { return true;}}}El comando se limita a implementar una sencilla interfaz:using System;using System.Web;public interface Command{void Do (HttpContext context);}En el caso de una aplicacin en la que el usuario debiese teneroportunidad de deshacer susacciones, lo nico que tendramos quehacer es aadirle un mtodo Undo a la interfazCommand (eimplementarlo correctamente en todas las clases que implementendichainterfaz, claro est).En vez de crear directamente los objetosde tipo Command, se utiliza una clase auxiliar en laque se incluyela lgica necesaria para elegir el comando adecuado. Esta fbricadecomandos (CommandFactory) se encargar de determinar el comandoadecuado enfuncin del contexto:using System;using System.Web;public class CommandFactory{public static Command Create(HttpContext context){string estilo =context.Request[«style»];Command command = new NullCommand();if ( estilo!=null && estilo.Equals(«vip»))command = newVIPCommand(context);elsecommand = new ConventionalCommand(context);return command;}}Para que nuestra aplicacin utilice el controlador creado, talcomo se describi en el captuloanterior al hablar de los filtrosHTTP, hemos de incluir lo siguiente en el fichero deconfiguracinWeb.config:134 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • Controlador comn para distintas pginas ASP.NETFinalmente, lo ltimo que nos falta es crear nuestra jerarqua decomandos, que sern los quese encarguen de personalizar elfuncionamiento de nuestra aplicacin para cada cliente:using System;using System.Web;public class AspNetCommand : Command{public void Do (HttpContextcontext){…context.Server.Transfer(url);}}En realidad, lo nico que hemos hecho ha sido reorganizar lasclases que implementan lainterfaz de nuestra aplicacin y reasignarlas responsabilidades de cada una de las clases. Si lohacemoscorrectamente, podemos conseguir un sistema modular con componentesdbilmenteacoplados que se pueden implementar y probar de formaindependiente. En la siguienteseccin veremos una forma ms generalde conseguir una aplicacin web fcilmentereconfigurable.Control de la aplicacinEn una aplicacin web, cada accin delusuario se traduce en una solicitud que da lugar a dosrespuestas dembito diferente. Por un lado, se ha de realizar la tarea indicadapor el usuario.Aparte, se le ha de mostrar al usuario la pginaadecuada, que puede no estar directamenterelacionada con la tarearealizada. De hecho, una misma pgina puede ser la respuestadelsistema ante distintas acciones y una misma accin puede darlugar a distintas pginas derespuesta en funcin del contexto de laaplicacin.En general, a partir del estado actual de la aplicacin(almacenado fundamentalmente en losdiccionarios Application ySession) y de la accin que realice el usuario, el sistema hadedecidir dos cosas: las acciones que se han de realizar sobre losobjetos con los que trabajala aplicacin y la siguiente pgina que hade mostrarse en el navegador del usuario.En el apartado anterior, vimos cmo los controladores se encargande tomar ambasdecisiones. Obviamente, el resultado no destaca porsu cohesin. En el mejor de los casos, lacohesin del controlador espuramente temporal. Es decir, las operaciones se incluyen en un135ASP.NET en la prcticahttp://csharp.ikor.org/
  • mdulo porque han de realizarse al mismo tiempo.Para organizar mejor una aplicacin, podemos dividir en dos laparte responsable de lainterfaz de usuario. Esta parte de laaplicacin se denomina habitualmente capa depresentacin. En la capade presentacin distinguir dos tipos bien diferenciadosdecomponentes:- Los componentes de la interfaz de usuario propiamente dichos:Los controlescon los que los usuarios interactan.- Los componentes de procesamiento de la interfaz de usuario(componentes deprocesamiento para abreviar): Estos componentes»orquestan los elementos de lainterfaz de usuario y controlan lainteraccin con el usuario».Esta distincin entre controles de la interfaz y componentes deprocesamiento nos permitediferenciar claramente las dosresponsabilidades distintas que antes les habamos asignado aloscontroladores MVC:- Los controles de la interfaz engloban las vistas del modeloMVC con las tareasrealizadas por los controladores MVC paraadquirir, validar, visualizar y organizarlos datos en la interfazde usuario.- Los componentes de procesamiento se encargan de mantener elestado de laaplicacin y controlar la navegacin del usuario a travsde sus distintas pginas.Cuando un usuario utiliza una aplicacin, lo hace con unobjetivo: satisfacer una necesidadconcreta. Una tcnica popular pararealizar el anlisis de los requisitos de una aplicacinconsiste enemplear casos de uso. Los casos de uso describen conjuntos deacciones que ha derealizar un usuario para lograr sus objetivos.Cada accin se realiza en un contexto deinteraccin determinado (unapgina en el caso de las aplicaciones web) y el usuario vapasando deun contexto de interaccin a otro conforme va completando etapas delcaso de usoque est ejecutando. Mientras que los controles de lainterfaz se encargan de garantizar elfuncionamiento de un contextode interaccin, los componentes de procesamiento controlan elflujode control de un caso de uso.Estos «componentes de procesamiento» se suelendenominarcontroladores de aplicacin, si bien hay que tener encuentaque estamos refirindonos a algo totalmente distinto a loquevimos en el apartado anterior cuando estudiamos laposibilidad deusar controladores MVC centralizados para unaaplicacin web. Enocasiones, para evitar malentendidos, sedenominan controladoresfrontales a los controladores MVCcentralizados, haciendo referenciaa que sirven de punto deacceso frontal para las aplicacionesweb.136 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • Los componentes de procesamiento de la interfaz de usuario,controladores de aplicacin deaqu en adelante, son responsables degestionar el flujo de control entre las distintaspginasinvolucradas en un caso de uso, decidir cmo afectan lasexcepciones que se puedan produciry mantener el estado de laaplicacin entre distintas interacciones (para lo cual acumulandatosrecogidos de los distintas pginas por las que va pasando elusuario) y ofrecerle a loscontroles de la interfaz los datos quepuedan necesitar para mostrrselos al usuario. De estaforma, sesepara por completo la visualizacin de las pginas del control de lanavegacin porla aplicacin.Esta estrategia nos permite, por ejemplo, crear distintasinterfaces para una aplicacin sintener que modificar ms que lasvistas correspondientes a los distintos contextos deinteraccin enque se puede encontrar el usuario. El controlador de la aplicacinpuede ser,por tanto, comn para una aplicacin Windows, una aplicacinweb y una aplicacin paraPDAs o telfonos mviles. Adems, se mejora lamodularidad del sistema, se fomenta lareutilizacin de componentes yse simplifica el mantenimiento de la aplicacin.Un controlador de aplicacin se suele implementar como unconjunto de clases a las que seaccede desde la interfaz de usuario,a modo de capa intermedia entre los controles de lainterfaz deusuario y el resto de la aplicacin. La siguiente clase ilustra elaspecto que podratener el controlador de una aplicacin web decomercio electrnico para el caso de usocorrespondiente a larealizacin de un pedido:public class ControladorPedido{private Cliente cliente; //Estado actual del pedidoprivate ArrayList productos;…public void MostrarPedido(){if (application.WebInterface) {… // InterfazwebSystem.Web.HttpContext.Current.Response.Redirect(«http://csharp.ikor.org/pedidos/Pedido.aspx»);} else {… // Interfaz WindowsFormPedido.Show();}}public void ElegirFormaDePago(){… // Seleccionar la forma depago ms adecuada para el cliente}public void RealizarPedido(){if (ConfirmarPedido()) {… // Crear el pedido con los datos facilitados}}137ASP.NET en la prcticahttp://csharp.ikor.org/
  • public bool ConfirmarPedido(){… // Solicitar una confirmacinpor parte del usuario}public void Cancelar(){… // Vuelta a la pgina/ventanaprincipal}public void Validar(){… // Comprobar que todo est en orden}}Si bien el recorrido del usuario a travs de la aplicacin lodetermina el controlador deaplicacin, las pginas concretas por lasque pase el usuario no tienen por qu estar prefijadasen el cdigodel controlador. Lo habitual es almacenar las transiciones entrepginas concretasen un fichero de configuracin aparte. La lgicacondicional para seleccionar la formaadecuada de mostrar lainterfaz de usuario tambin se puede eliminar del cdigodelcontrolador de aplicacin si se crea un interfaz genrico quepermita mostrar un contexto deinteraccin a partir de una URLindependientemente de si estamos construyendo unaaplicacin Windowso una aplicacin web.Separar fsicamente el controlador de aplicacin de los controlesde la interfaz de usuariotiene otras ventajas. Por ejemplo, unusuario podra intentar realizar un pedido y encontrarsecon algntipo de problema. Entonces, podra llamar por telfono para que uncomercialcompletase los pasos pendientes de su pedido sin tener querepetir el proceso desde elprincipio. De hecho, quiz utilice paraello una aplicacin Windows que comparte con laaplicacin web elcontrolador de aplicacin.Por otro lado, los controladores de aplicacin permiten que unusuario pueda realizar variastareas en paralelo. Por ejemplo, elusuario podra tener abiertas varias ventanas de sunavegador y dejarla realizacin de un pedido a medias mientras consultaba el catlogodeprecios de productos alternativos, por ejemplo. Al encargarsecada controlador de mantener elestado de una nica tarea, seconsigue una simplificacin notable en el manejo deactividadesconcurrentes.En el caso de las aplicaciones web ASP.NET, los controladores deaplicacin son los objetosalmacenados como estado de la aplicacin enla variable Session. Los manejadores deeventos de las pginas .aspxaccedern a dichos controladores en respuesta a las accionesdelusuario.En el caso de las aplicaciones Windows, los formulariosincluirnuna variable de instancia que haga referencia alcontrolador deaplicacin concreto. Usar variables globalesnunca es una buena idea.Y mucho menos en este mbito.138 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • El controlador de aplicacin se coloca entre el modelo y lainterfaz deusuario para orquestar la ejecucin de los casos deuso.Centremos ahora nuestra atencin en el diseo del controlador deaplicacin. Bsicamente,tenemos que considerar tres aspectosfundamentales a la hora de construir el controladordeaplicacin:- La creacin de vistas: Un controlador concreto podra estarasociado a distintasvistas en funcin de la situacin (por ejemplo,cuando se utiliza el mismocontrolador para una aplicacin web y unaaplicacin Windows). Lo normal sercrear una clase abstracta convarias subclases concretas para cada tipo de interfaz.En funcin dela configuracin de la aplicacin, se instanciar una ventana ounapgina .aspx. Lo importante es no tener que incluir la seleccinde la vistaconcreta en el cdigo del controlador. Esto es, todo locontrario de lo que hicimospara ilustrar el aspecto general de uncontrolador de aplicacin.- La transicin entre vistas: Esto resulta ms sencillo si leasignamos unidentificador nico a cada vista. Este identificador setraducir a la URLcorrespondiente en el caso de las aplicacionesweb, mientras que en unaaplicacin Windows conducir a la creacin deun formulario de un tipo concreto.De hecho, el mapa de navegacincompleto de una aplicacin puede almacenarsecomo un documento XMLfcilmente modificable que describa el diagrama deestados de cadacaso de uso del sistema.- El mantenimiento del estado de las tareas realizadas por elusuario: Lo mssencillo es que el estado de la aplicacin se mantengaen memoria o como partedel estado de la aplicacin web. Enocasiones, no obstante, puede interesaralmacenar el estado delcontrolador de forma permanente (en una base de datos,por ejemplo)para permitir que el usuario pueda reanudar tareas que dejaseamedias en sesiones anteriores.139ASP.NET en la prcticahttp://csharp.ikor.org/
  • Aspecto visual de la aplicacinEn el apartado anterior hemos visto distintas formas deorganizar las partes de nuestraaplicacin relacionadas con lainterfaz de usuario. Las decisiones de diseo tomadas nosayudan amejorar la calidad del diseo interno de nuestra aplicacin, si bienesas decisionesno son visibles desde el exterior. De hecho, a lahora de desarrollar una aplicacin, resultarelativamente fcilolvidar algunos de los factores que influyen decisivamente enlapercepcin que tiene el usuario de nuestra aplicacin. Al fin y alcabo, para el usuario, eldiseo de la aplicacin es el diseo de suinterfaz. Y en este caso nos referimosexclusivamente al aspectovisual de la aplicacin, no al diseo modular de su capa msexterna.De ah la importancia que tiene conseguir un aspecto visualcoherente en nuestrasaplicaciones (aparte de un comportamientohomogneo que facilite su uso por parte delusuario).En esteapartado, veremos cmo se pueden utilizar distintas estrategias paraconseguir ennuestras aplicaciones un aspecto visual consistente.Adems, lo haremos intentando evitarcualquier tipo de duplicacin, yaque la existencia de fragmentos duplicados en distintaspartes deuna aplicacin no hace ms que dificultar su mantenimiento. Por otrolado, tambinnos interesa separar la implementacin de nuestraimplementacin de los detallesrelacionados con el diseo grfico de lainterfaz de usuario, de forma que sta se puedamodificar librementesin afectar al funcionamiento de la aplicacin.Cualquier aplicacin web, sea del tipo que sea, suele constar dedistintas pginas. Esaspginas, habitualmente, compartirn algunoselementos, como pueden ser cabeceras, pies depgina, mens o barrasde navegacin. Por lo general, en el diseo de la aplicacin secrearun boceto de la estructura que ha de tener la interfaz de laaplicacin, tal como se muestra enla figura.140 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • El espacio disponible en la interfaz de usuario se sueledistribuir de lamisma forma para todas las pginas de la aplicacinweb.En la creacin de sitios web, la distribucin del espaciodisponible para los distintoscomponentes de las pginas se puedeefectuar, en principio, de dos formas diferentes:utilizando marcos(frames) para cada una de las zonas en las que dividamos elespaciodisponible, o empleando tablas con una estructura fija queproporcione coherencia a lasdistintas pginas de nuestra aplicacin.Si utilizamos marcos, cada marco se crea como unapgina HTMLindependiente. En cambio, si optamos por usar tablas, cada pginasdeberincluir repetidos los elementos comunes a las distintaspginas. Si nuestro anlisis se quedaseah, obviamente nosdecantaramos siempre por emplear marcos.Desgraciadamente, el uso de marcos tambin presentainconvenientes. En primer lugar, unapgina creada con marcos no sever igual siempre: en funcin del navegador y del tamaodel tipo deletra que haya escogido el usuario, una pgina con marcos puederesultarcompletamente inutilizable. En segundo lugar, si losusuarios no siempre acceden a nuestraspginas a travs de la pginaprincipal, como puede suceder si utilizan los enlacesproporcionadospor un buscador, slo vern en su navegador el contenido de uno delosmarcos. En este caso, no podrn navegar por las distintas pginasde nuestro sistema sielementos de la interfaz como la barra denavegacin se muestran en marcos independientes.Las desventajas mencionadas de los marcos han propiciado que,casi siempre, las interfacesweb se construyan utilizando tablas.Desde el punto de vista del programador, esto implicaquedeterminados elementos de la interfaz aparecern duplicados en todaslas pginas de unaaplicacin, por lo que se han ideado distintosmecanismos mediante los cuales se puedengenerar dinmicamente laspginas sin necesidad de que fsicamente existanelementosduplicados.141ASP.NET en la prcticahttp://csharp.ikor.org/
  • Filtros con mdulos HTTPLa primera idea que se nos puede ocurrires interceptar todas las solicitudes que llegan alservidor HTTP, detal forma que podamos realizar tareas de preprocesamientoopostprocesamiento sobre cada solicitud HTTP. En ASP.NET, esto sepuede realizar utilizandomdulos HTTP.Los mdulos HTTP funcionan como filtros que reciben lassolicitudes HTTP antes de questas lleguen a las pginas ASP.NET.Dichos mdulos han de ser completamenteindependientes y este hechopermite que se puedan encadenar varios mdulos HTTP yconstruirfiltros complejos por composicin. Usualmente, estos mdulos seutilizan pararealizar tareas a bajo nivel, como puede ser el manejode distintos juegos de caracteres, el usode tcnicas criptogrficas,la compresin y decompresin de datos, la codificacin ydecodificacinde URLs, o la monitorizacin del funcionamiento del sistema. Noobstante,tambin se pueden utilizar como «decoradores», para aadirlefuncionalidad de formatransparente a las pginas ASP.NET a las queaccede el usuario. Sin tener que modificar laspginas en s, queseguirn siendo independientes, se puede hacer que los mdulos HTTPseencarguen de las tareas comunes a todas las pginas de unaaplicacin web.Entre las ventajas de los mdulos HTTP destaca su independencia,al ser totalmenteindependientes del resto de la aplicacin. Estaindependencia les proporciona una granflexibilidad, ya que puedencombinarse libremente distintos mdulos HTTP. Adems, permitesuinstalacin dinmica en una aplicacin, algo conocido como hotdeployment en ingls.Finalmente, al ser componentes completamenteindependientes, son ideales para sureutilizacin en distintasaplicaciones. Un claro ejemplo de esto es elmduloSessionStateModule, que se encarga del mantenimiento de lassesiones de usuario entodas las aplicaciones web ASP.NET.ASP.NET proporciona una serie de eventos que se producen duranteel procesamiento de unasolicitud HTTP a los que se pueden asociarfragmentos de cdigo. Simplemente, tendremosque crear un mdulo HTTP,que no es ms que una clase que implemente la interfazIHttpModule.Dicha clase incluir un mtodo Init en el que indicaremos los eventosqueestemos interesados en capturar. El siguiente ejemplo muestracmo podemos aadir lo quequeramos al comienzo y al final de larespuesta generada por nuestra aplicacin:using System;using System.Web;public class DecoratorModule : IHttpModule{public void Init(HttpApplication application){application.BeginRequest += newEventHandler(this.BeginRequest);application.EndRequest += newEventHandler(this.EndRequest);}142 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • private void BeginRequest (Object source, EventArgse){HttpApplication application =(HttpApplication)source;HttpContext context =application.Context;context.Response.Write(«Cabecera»);}private void EndReq uest (Object source, EventArgse){HttpApplication application =(HttpApplication)source;HttpContext context =application.Context;context.Response.Write(» Berzal, Cortijo,Cubero»);}public void Dispose(){}}Una vez que tengamos implementado nuestro mdulo HTTP, lo nicoque nos falta esincluirlo en la seccin httpModules del fichero deconfiguracin Web.config para quese ejecute en nuestra aplicacinweb.donde DecoratorModule es el nombre de la clase que implementa elmdulo ybiblioteca es el nombre del assembly que contiene dichaclase (esto es,biblioteca.dll).Al ejecutarse siempre que se recibe una solicitud HTTP, y conelobjetivo de evitar que se conviertan en un cuello de botellaparanuestras aplicaciones, es esencial que los mdulos HTTPseaneficientes.La directiva #includeUtilizando mdulos HTTP se puede conseguirque nuestras pginas ASP.NET le lleguen alusuario como una parte dela pgina web que se visualiza en su navegador. Lo mismo sepodralograr si se crean controles por composicin que representen lacabecera, la barra denavegacin, el men o el pie de las pginas. Eneste caso, no obstante habr que colocar amano dichos controles encada una de las pginas de la aplicacin, lo que resulta mstedioso143ASP.NET en la prcticahttp://csharp.ikor.org/
  • y propenso a errores.Afortunadamente, ASP.NET nos ofrece un mecanismo ms sencillo quenos permiteconseguir el mismo resultado sin interferir el endesarrollo de las distintas pginas de unaaplicacin. Nos referimos ala posibilidad de incluir en la pgina .aspx un comentario conladirectiva #include al ms puro estilo del lenguaje de programacinC. Este mecanismo, encierto modo, ya lo estudiamos cuandoanalizamos el uso de controladores de pgina enASP.NET y, en suversin ms bsica, su utilizacin se puede resumir en los siguientespasos:- Se crean las partes comunes de las pginas en ficheros HTMLindependientes.- Se implementan las distintas pginas de la aplicacin como si setratase depginas independientes.- Se incluyen las directivas #include en el lugar adecuado delas pginas.aspx.Por ejemplo, puede que deseemos aadir a una pgina web laposibilidad de que el visitantenos enve ficheros a travs de la web,lo que puede ser til en una aplicacin web para laorganizacin de uncongreso o para automatizar la entrega de prcticas de unaasignatura. Elformulario en s ser muy simple, pero nos gustara quequedase perfectamente integrado conel resto de las pginas web denuestro sistema. En ese caso, podemos crear un ficheroheader.inccon la cabecera completa de nuestras pginas y otro ficherofooter.inccon todo lo que aparece al final de nuestras pginas. Envez de incluir todo eso en nuestrapgina .aspx, lo nico que haremosser incluir las directivas #include en loslugarescorrespondientes:…Esta estrategia de implementacin es la ideal si las partescomunes de nuestras pginas sonrelativamente estticas. Si no lo son,lo nico que tenemos que hacer es crear una jerarqua decontroladoresde pgina, tal como se describi cuando estudiamos el uso del modeloMVC enASP.NET.144 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • Aspecto visual de un formulario ASP.NET creado para laorganizacin deun congreso. El fichero .aspx slo incluye lasdirectivas #include y loscontroles propios del formulario. El aspecto visual final es elresultado decombinar el sencillo formulario con los detalles depresentacin de lapgina, que se especifican en los ficheros header.inc yfooter.inc.PlantillasEn vez de que cada pgina incluya los detallescorrespondientes a una plantilla general,podemos seguir laestrategia opuesta: crear una plantilla general en la cual se vasustituyendoen contenido manteniendo el aspecto general de lapgina. Para implementar esta estrategia enASP.NET, se nos ofrecendos opciones: usar una pgina maestra o utilizar un controlmaestro.Pgina maestraEl uso de una pgina maestra se puede considerarcomo una forma de crear un controlador145ASP.NET en la prcticahttp://csharp.ikor.org/
  • MVC de aplicacin. El usuario siempre acceder a la misma pgina.aspx pero su contenidovariar en funcin del estado de la sesin. Enla pgina maestra se reserva un espacio paramostrar un control uotro en funcin de la solicitud recibida. El evento Page_Load delapgina maestra contendr, entonces, algo similar a losiguiente:void Page_Load (object sender, System.EventArgs e){ControlmiControl = LoadControl («fichero.cs.ascx»);this.Controls.Add (miControl);}En el cdigo de la pgina maestra se tendr que decidir cul es elcontrol concreto que semostrar en el espacio reservado al efecto.Mantener el aspecto visual de las pginas de laaplicacin es unaconsecuencia directa de la forma de implementar la aplicacin, igualque elhecho de que no se pueden utilizar los mecanismosproporcionados por ASP.NET pararestringir el acceso a las distintaspartes de la aplicacin (por el simple hecho de que siemprese accedea la misma pgina). Adems, como las solicitudes han de incluir lainformacinnecesaria para decidir qu pgina mostrar, este hecho haceespecialmente vulnerable a nuestraaplicacin frente a posiblesataques. Deberemos ser especialmente cuidadosos para que unusuarionunca pueda acceder a las partes de la aplicacin que se supone nopuede ver.Control maestroPara evitar los inconvenientes asociados a la creacin de unapgina maestra, se puede utilizarun control maestro que se incluyaen distintas pginas ASP.NET. El control maestro realizalas mismastareas que la pgina maestra, salvo que, ahora, el usuario accede adistintaspginas .aspx.El control maestro se crea como cualquier otro control definidopor el usuario en ASP.NET, sibien ha de definir el aspecto visualgeneral de las pginas de nuestra aplicacin e incluir unazonamodificable. En esta zona modificable, que puede ser una celda deuna tabla, sevisualizar el contenido que cambia dinmicamente de unapgina a otra de la aplicacin.La aplicacin, por tanto, constar de un conjunto de pginas .aspx,cada una de las cualesincluye una instancia del control maestro. Alacceder a una pgina, en el evento Form_Load,se establecer elcontrol concreto que ha de mostrar el control maestro.146 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • Configuracin dinmica de la aplicacinLos captulos anteriores sirvieron para que nos familiarizsemoscon la construccin deaplicaciones web en la plataforma .NET. En lassecciones anteriores vimos cmo se puedenorganizar las distintaspartes de una aplicacin web directamente relacionadas con lainterfazde usuario. Por otro lado, analizamos distintas formas decrear aplicaciones web consistentesy homogneas, adems de fcilmentemantenibles. Ahora, ha llegado el momento de dotar decontenido alas pginas .aspx que conforman nuestras aplicaciones ASP.NET.Los controles incluidos como parte de la biblioteca de clases dela plataforma .NET ofrecenun mecanismo conocido con el nombre de»enlace de datos» [data binding] mediante el cualpodemos asociarlesvalores de forma dinmica a sus propiedades. Este mecanismonospermite, por ejemplo, mostrarle al usuario conjuntos de datos deuna forma flexible, cambiarlas opciones existentes a su disposicino modificar el aspecto de la aplicacin en funcin delas preferenciasdel usuario, todo ello sin tener que modificar una sola lnea decdigo eindependientemente de dnde provengan los datos que permitenmodificar las propiedades delos controles de nuestra aplicacin.Esos datos pueden provenir de una simple coleccin, deun fichero XMLo de un DataSet que, posiblemente, hayamos obtenido a partir de losdatosalmacenados en una base de datos convencional.A grandes rasgos, se puede decir que existen tres formasdiferentes de asociarles valores a laspropiedades de los controlesde la interfaz grfica:- Como primera opcin, podemos especificar los valores quedeseemos comoatributos de las etiquetas asociadas a los controles(esto es, dentro de ). Si estamos utilizando un entorno dedesarrollo como el Visual Studio .NET,estos valores los podemosfijar directamente desde la ventana de propiedades.Obviamente, asse le asignan valores a las propiedades de los controles deformaesttica, no dinmica.- Una alternativa consiste en implementar fragmentos de cdigoque hagan uso delmodelo orientado a objetos asociado a loscontroles de nuestros formularios. Estoes, como respuesta a algnevento, como puede ser el evento Form_Load de unformulario web,establecemos a mano los valores adecuados para las propiedadesquedeseemos modificar. sta es una opcin perfectamente vlida pararellenarvalores o listas de valores cuando stos se obtienen apartir del estado de la sesinde usuario.- Por ltimo, la alternativa ms flexible consiste en obtener dealguna fuente dedatos externa los valores que vamos a asociar a unapropiedad de un control. Estaestrategia es extremadamente til parasimplificar la implementacin ensituaciones ms complejas. Laplataforma .NET nos ofrece un mecanismo,conocido con el nombre de»enlace de datos», que nos facilita el trabajo en este147ASP.NET en la prcticahttp://csharp.ikor.org/
  • contexto. En primer lugar, debemos disponer de un objeto quecontenga losvalores en cuestin, ya sea una simple coleccin (como unvector, instancia de laclase Array en .NET) o algo ms sofisticado(como un DataSet de los usadosen ADO.NET). A continuacin,simplemente tenemos que asociarle ese objeto ala propiedad adecuadadel control. El enlace de datos se realizarautomticamente cuandoinvoquemos el mtodo DataBind asociado al control.El mecanismo de enlace de datos ofrece varias ventajas conrespecto a la forma tradicional derellenar dinmicamente los valoresde las propiedades de un control (que, recordemos,consiste enimplementar las asignaciones correspondientes). La primera de ellases que nospermite separar claramente el cdigo de nuestra aplicacinde la interfaz de usuario. Al crearun nivel extra de indireccin, sedesacoplan los conjuntos de valores de las propiedades deloscontroles a las que luego se asignan. Adems, el mecanismo estimplementado de tal formaque podemos enlazar las propiedades de uncontrol a una amplia variedad de fuentes de datos.Es decir, losvalores pueden provenir de colecciones (de cualquier tipo de losdefinidos en labiblioteca de clases .NET, desde Array hastaHashtable), pero tambin pueden provenirde conjuntos de datosADO.NET (como el verstil DataSet, la tabla DataTable, lavistaDataView o el eficiente DataReader), los cuales, a su vez,pueden construirse a partir deuna consulta sobre una base de datosrelacional o a partir de un fichero XML. De hecho,cualquier objetoque implemente la interfaz IEnumerable puede usarse como fuentededatos. La existencia de esta interfaz permite que, vengan dedonde vengan los valores, laimplementacin del enlace sea siempre lamisma, lo que simplifica enormemente elmantenimiento de laaplicacin cuando cambian nuestras fuentes de datos.Otro aspecto que siempre debemos tener en mente es que el enlaceno es del todo dinmico enASP.NET. A diferencia de los formulariosWindows, los cambios que se produzcan en loscontroles ASP.NET quemuestran los datos no se propagan al conjunto de datos. Enrealidad,el mecanismo de enlace de datos en ASP.NET se limita arellenar las propiedades quehayamos enlazado una nica vez. Si, porel motivo que sea, nuestro conjunto de datos cambiay queremos queese cambio se refleje en la interfaz de usuario, seremos nosotroslos nicosresponsables de hacer que los cambios se reflejen en elmomento adecuado.De forma anloga a las etiquetas JSP que se empleanpara construir aplicaciones web conJava, en las pginas ASP.NET sepueden incluir expresiones de enlace de datos de la forma. Un pocoms adelante veremos algunos ejemplos que ilustrarn suutilizacin enla prctica. En las siguientes secciones, comenzaremos a ver cmofunciona elenlace de datos en una amplia gama de situaciones.El mecanismo de enlace de datos se puede utilizar tanto enlaconstruccin de aplicaciones Windows como en la creacindeaplicaciones web con ASP.NET. No obstante, en esteltimo caso, elenlace es unidireccional. Los formulariosWindows permitenautomatizar las actualizaciones en elconjunto de datos. En ASP.NET,las actualizacionestendremos que implementarlas manualmente.148 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • Listas de opcionesComencemos por el caso ms sencillo (y comn)que se nos puede presentar a la hora de crearla interfaz de usuariode nuestra aplicacin. Es habitual que, en un formulario,determinadoscampos puedan slo tomar un valor dentro de un conjuntode valores preestablecido, comopueden ser el estado civil o lanacionalidad de una persona, el mtodo de pago o la forma deenvo deun pedido. En el caso de ASP.NET, para este tipo de camposutilizaremos alguno delos siguientes controles:- un conjunto de botones de radio asp:RadioButtonList, paramostrar unconjunto de opciones mutuamente excluyentes,- un conjunto de botones de comprobacin asp:CheckBoxList, cuandolasdistintas opciones no son mutuamente excluyentes,- una lista convencional de tipo asp:Listbox, o, incluso,- una lista desplegable de valores asp:DropDownList (cuando nodispongamosde demasiado espacio en pantalla).Sea cual sea el control utilizado, los valores permitidos sedefinen utilizando componentes detipo asp:ListItem. Si, porejemplo, desesemos mostrar una lista de opciones quepermitiese alusuario seleccionar una zona geogrfica determinada, podramosescribir a manolo siguiente (o emplear el editor de propiedadespara la coleccin Items del controlcorrespondiente a la lista):Sin embargo, resulta mucho ms adecuado utilizar una fuente dedatos independiente pararellenar la lista. Si no, qu sucederacuando nuestra aplicacin abarcase un rea geogrfica149ASP.NET en la prcticahttp://csharp.ikor.org/
  • ms amplia? Tendramos que ir modificando, una por una, todas laslistas de este tipo quetuvisemos repartidas por la aplicacin.El mecanismo de enlace de datos nos es extremadamente til enestas situaciones, ya que nospermite rellenar las listas de valorespermitidos a partir de los datos obtenidos de algunafuente externaque tengamos a nuestra disposicin. Si la lista de opciones setuviese quemodificar, slo habra que modificar la fuente de datos,que debera ser nica, y no loselementos de la lista en todos loslugares donde apareciesen. En definitiva, se separa porcompleto lainterfaz de la aplicacin de los datos con los que trabaja laaplicacin, con lo quesu mantenimiento resultar ms sencillo.Ahora veremos cmo podemos rellenar dinmicamente una lista deopciones mostrada a partirde distintas fuentes de datos. Enconcreto usaremos distintos tipos de colecciones y ficherosXML quenos permitirn configurar dinmicamente muchas partes de nuestrasaplicaciones.Vectores simples: Array y ArrayListLa clase System.Array es la clase que representa un vector en laplataforma .NET y sirvecomo base para todas las matrices en C#. Porsu parte, la claseSystem.Collections.ArrayList nos permite crearvectores de tamao dinmico.Ambas clases implementan el mismoconjunto de interfaces (IList, ICollection,IEnumerable, ICloneable)y pueden utilizarse para enlazar colecciones de datos alaspropiedades de un control.Al cargar la pgina ASP.NET, en el evento Form_Load, obtenemos lalista de valores y se laasociamos a la propiedad DataSource de lalista de opciones. Para rellenar la lista deopciones con losvalores incluidos en la coleccin de valores, no tenemos ms quellamar almtodo DataBind() del control:private void Page_Load(object sender, System.EventArgs e){if(!Page.IsPostBack) {ArrayList list = new ArrayList();list.Add(«Granada»);list.Add(«Almera»);list.Add(«Mlaga»);list.Add(«Jan»);list.Add(«Crdoba»);list.Add(«Sevilla»);list.Add(«Cdiz»);list.Add(«Huelva»);list.Sort();provincia.DataSource = list;provincia.DataBind();}}150 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • Lista de opciones creada dinmicamente a partir de unacoleccin.Para simplificar el ejemplo, en el mismo evento Form_Load hemoscreado la lista de tipoArrayList y hemos aadido los valorescorrespondientes a las distintas opciones con elmtodo Add(). Unavez que tenemos los elementos en la lista, los hemos ordenadollamandoal mtodo Sort(). Si hubisemos querido mostrarlos en ordeninverso, podramos haberusado el mtodo Reverse() una vez que lostuvisemos ordenados.Finalmente, el enlace de la coleccin con el control se realizamediante la propiedadDataSource del control y la llamada al mtodoDataBind() cuando queremos rellenar lalista. En este caso, loselementos del vector se utilizan como texto (Text) y comovalor(Value) asociado a los distintos elementos ListItem de lalista, si bien esto no tiene porqu ser as siempre, como veremos acontinuacin.Pares clave-valor: Hashtable y SortedListGeneralmente, cuando utilizamos listas de opciones en lainterfaz de usuario, una cosa es elmensaje que vea el usuarioasociado a cada opcin y otra muy distinta es el valorqueinternamente le asignemos a la opcin seleccionada. El mensajevara, por ejemplo, si nuestra151ASP.NET en la prcticahttp://csharp.ikor.org/
  • aplicacin est localizada para varios idiomas, mientras que elvalor asociado a la opcin serfijo. Incluso aunque nuestra aplicacinslo funcione en castellano, es buena idea que, en lasopciones deuna lista, texto y valor se mantengan independientes. El textosuele ser msdescriptivo y puede variar con mayor facilidad. Adems,no nos gustara que un simplecambio esttico en el texto de una opcinhiciese que nuestra aplicacin dejase de funcionarcorrectamente.Cuando queremos asignarle dos valores a las propiedades de cadauna de las opciones de unalista, un simple vector no nos essuficiente. Hemos de utilizar colecciones que almacenenparesclave-valor, como es el caso de las colecciones que implementan lainterfazIDictionary, como pueden ser Hashtable o SortedList.Una tabla hash, implementada en la biblioteca de clases .NET porla claseSystem.Collections.Hashtable, es una estructuras de datosque contiene paresclave-valor y est diseada para que el acceso a unvalor concreto sea muy eficiente, O(1)utilizando la terminologahabitual en el anlisis de algoritmos. En nuestro ejemplo de lalistade provincias, podramos utilizar una tabla hash para almacenarcomo clave el cdigocorrespondiente a una provincias y como valor sunombre completo. La clave la asociamos alvalor de la opcin(DataValueField) y, el nombre, al texto de la etiqueta asociada alaopcin (DataTextField):private void Page_Load(object sender, System.EventArgs e){if(!Page.IsPostBack) {Hashtable table = new Hashtable();table.Add(«GR», «Granada»);table.Add(«AL»,»Almera»);table.Add(«MA», «Mlaga»);table.Add(«J»,»Jan»);table.Add(«CO», «Crdoba»);table.Add(«SE»,»Sevilla»);table.Add(«CA», «Cdiz»);table.Add(«HU», «Huelva»);provincia.DataSource =table;provincia.DataValueField=»Key»;provincia.DataTextField=»Value»;provincia.DataBind();}}El nico inconveniente de usar tablas hash es que no se puedeelegir el orden de presentacinde los elementos de la lista. Paraque las opciones de la lista aparezcan ordenadas tenemosque usaruna coleccin como la proporcionada por laclaseSystem.Collections.SortedList, que se emplea exactamente igualque la tablahash y mantiene sus elementos ordenados de formaautomtica.152 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • Ficheros XMLHoy en da, la opcin ms comnmente utilizada para configurardinmicamente unaaplicacin consiste en la utilizacin de ficheros XMLauxiliares que contengan los datosnecesarios para configuraradecuadamente una aplicacin. A partir de datos guardados enficherosXML, se puede personalizar el men de opciones visible para unusuario en funcinde sus permisos, cambiar el aspecto visual de laspginas de la aplicacin en funcin de laspreferencias de un usuarioconcreto o, incluso, instalar distintas «versiones» de unamismaaplicacin para distintos clientes.En el caso de una aplicacin web ASP.NET, para leer un ficheroXML slo tenemos queteclear lo siguiente:DataSet dataset = new DataSet();dataset.ReadXml (Server.MapPath(«fichero.xml») );La funcin ReadXml() construye un conjunto de datos a partir delcontenido de un ficheroXML. La funcin Server.MapPath() es la quenos permite buscar el ficherodinmicamente en el lugar adecuado;esto es, en el directorio donde tengamos instalada laaplicacinweb.Si volvemos a nuestro ejemplo simpln, el de la lista deprovincias, podemos crear un ficheroXML auxiliar para rellenar lalista de opciones a partir de dicho fichero. Este ficheropuedetener el siguiente formato:ALAlmera…GRGranada…Una vez que tenemos el fichero con los datos, lo nico quetenemos que hacer en el cdigo denuestra aplicacin es cargar dichofichero en un conjunto de datos creado al efecto y enlazarelconjunto de datos al control que representa la lista de opciones.El resultado es bastantesencillo y cmodo de cara al mantenimientofuturo de la aplicacin:153ASP.NET en la prcticahttp://csharp.ikor.org/
  • private void Page_Load(object sender, System.EventArgse){DataSet dataset;if (!Page.IsPostBack) {dataset = newDataSet();dataset.ReadXml(MapPath(«provincias.xml»));provincia.DataSource =dataset;provincia.DataValueField=»id»;provincia.DataTextField=»nombre»;provincia.DataBind();}}Obsrvese cmo se realiza en enlace de datos con los elementos delfichero XML: elelemento id se hace corresponder con el valorasociado a una opcin de la lista, mientras queel elemento nombreser lo que se muestre como etiqueta asociada a cada opcin.Caso prcticoEn captulos anteriores pusimos como ejemplo una sencilla listade contactos pero nosdejamos en el tintero cmo se crea dinmicamentela lista desplegable a partir de la cualpodemos ver los datosconcretos de cada uno de nuestros contactos. Ahora, ya estamosendisposicin de ver cmo se construye dinmicamente esa lista paracompletar nuestra sencillaaplicacin de manejo de una agenda decontactos.El formulario que nos permite ver los datos de una lista decontactos.Antes de ver cmo se rellena esa lista desplegable, no obstante,nos hacen falta algunasrutinas auxiliares que nos permitan leer yescribir los datos asociados a cada contacto. Paralograrlo, podemosutilizar las facilidades que nos ofrece la plataforma .NET paraserializarobjetos en XML, algo que podemos implementar de formagenrica en una clase auxiliar:154 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • using Systemusing System.IO;using System.Xml;usingSystem.Xml.Serialization;public class Utils{// Serializacinpublic static void Serialize (object obj, stringfilename){XmlSerializer serializer = new XmlSerializer(obj.GetType());TextWriter writer = new StreamWriter (filename,false,System.Text.Encoding.GetEncoding(«ISO-8859-1»));serializer.Serialize(writer, obj);writer.Close();}// Deserializacinpublic static object Deserialize (Type type, stringfilename){object obj = null;XmlSerializer serializer = newXmlSerializer (type);TextReader stream = new StreamReader(filename,System.Text.Encoding.GetEncoding(«ISO-8859-1»));XmlReader reader= new XmlTextReader(stream);if (serializer.CanDeserialize(reader))obj =serializer.Deserialize (reader);reader.Close();stream.Close();return obj;}}Las utilidades definidas en la clase anterior, cuando lasaplicamos sobre objetos de tipoContact (la clase que utilizamospara encapsular los datos que tenamos de un contactoconcreto), danlugar a ficheros XML de la siguiente forma:[email protected] casa de su dueoYorkshireTerrierimage/mota.jpg155ASP.NET en la prcticahttp://csharp.ikor.org/
  • Ahora bien, volvamos a nuestra aplicacin web. Supongamos que losdatos relativos anuestros contactos los almacenamos en unsubdirectorio denominado contacts deldirectorio que aloja nuestraaplicacin web. Para leer desde un fichero XML los datos deuncontacto, lo nico que tendremos que hacer es escribir algosimilar a lo siguiente:private Contact GetContact (string filename){FileInfo fi = newFileInfo( Server.MapPath(«contacts»)+»/»+filename );return (Contact) Utils.Deserialize(typeof(Contact), fi.FullName);}Por tanto, ya sabemos cmo leer los datos de un contacto. Lo nicoque nos falta es rellenar lalista desplegable de opciones que nosservir de ndice en nuestra agenda de contactos. Eso esalgo quepodemos hacer fcilmente a partir de lo que ya sabemos:private void Page_Load(object sender, System.EventArgse){DirectoryInfo di;SortedList list;FileInfo[] fi;Contactcontact;if (!Page.IsPostBack) {list = new SortedList();di = new DirectoryInfo( Server.MapPath(«contacts») );if (di!=null) {fi = di.GetFiles();foreach (FileInfo file in fi) {contact = GetContact( file.Name);list.Add(contact.Name, file.Name);}ContactList.DataSource = list;ContactList.DataTextField =»Key»;ContactList.DataValueField =»Value»;ContactList.DataBind();Header.Visible = false;ContactList.SelectedIndex = 0;}} else {UpdateUI();}}156 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • A partir del contenido del directorio donde almacenamos losdatos, vemos los ficheros quehay y creamos una entrada en la listadesplegable. Para saber en cada momento cul es elcontacto cuyosdatos hemos de mostrar, lo nico que tenemos que hacer es ver cul eslaopcin seleccionada de la lista desplegable. Dicha opcin vienedada por la propiedadSelectedItem de la lista:private void UpdateUI (){string filename;Contact contact;if (ContactList.SelectedItem!=null) {filename =ContactList.SelectedItem.Value;contact =GetContact(filename);LabelContact.Text =ContactList.SelectedItem.Text;ShowContact(contact);}}Finalmente, slo nos queda hacer que, siempre que el usuarioseleccione una de las opcionesde la lista, los datos que semuestren correspondan a la opcin seleccionada. Para lograrlo,slotenemos que redefinir la respuesta de nuestro formulario aleventoSelectedIndexChanged de la lista desplegable:private void ContactList_SelectedIndexChanged(object sender,System.EventArgs e){UpdateUI();}Con esto se completa la sencilla agenda de contactos queempezamos a construir hace un parde captulos al comenzar nuestroaprendizaje sobre ASP.NET. No obstante, an nos quedanalgunos temaspor tratar, entre los que se encuentra la visualizacin de conjuntosde datos enlos formularios ASP.NET por medio de controles como losque se estudiarn en la siguienteseccin.Conjuntos de datosLa mayor parte de las aplicaciones trabajancon conjuntos de datos. Dado que es bastantenormal tener quemostrar un conjunto de datos en una tabla o en un informe, tambinlo esque la biblioteca de clases de la plataforma .NET incluyacontroles que permitan visualizarconjuntos de datos. En esta seccinveremos los tres controles que se utilizan con este fin enlaplataforma .NET y mostraremos cmo se les pueden enlazar conjuntosde datos.157ASP.NET en la prcticahttp://csharp.ikor.org/
  • El control asp:RepeaterLa etiqueta asp:Repeater corresponde a un control ASP.NET quepermite mostrar listasde una forma ms verstil que los controlesvistos en la seccin anterior. El controlasp:Repeater, implementadopor la claseSystem.Web.UI.WebControls.Repeater, permite aplicar unaplantilla a lavisualizacin de cada uno de los elementos delconjunto de datos.Dichas plantillas, que deberemos crear a mano,especifican el formato en el que se mostrarcada elemento,usualmente mediante el uso de las etiquetas asociadas a la creacinde tablasen HTML. Para crear una tabla, se incluye la etiqueta decomienzo de la tabla y lacabecera de la misma en la plantillaHeaderTemplate, que corresponde a la cabeceragenerada por elcontrol asp:Repeater antes de mostrar los datos. De forma anloga,laetiqueta de cierre de la tabla se incluye en la plantillaFooterTemplate delcontrol asp:Repeater. Por su parte, cada uno delos elementos del conjunto de datos semostrar tal comoespecifiquemos en la plantilla ItemTemplate, que estar delimitadaporlas etiquetas HTML y , correspondientes a una fila de la tabla.Como mnimo,un control asp:Repeater debe incluir la definicin de laplantilla ItemTemplate.Todas las dems plantillas sonopcionales.Veamos, en la prctica, cmo funciona el control asp:Repeater conel ejemplo quepusimos en la seccin anterior. En primer lugar,tenemos que aadir un controlasp:Repeater al formulario web con elque estemos trabajando. A continuacin, podemosobtener el conjuntode datos desde el fichero XML utilizado en el ltimo ejemplo delaseccin anterior. Dicho conjunto de datos hemos de enlazarlo alcontrol asp:Repeater, loque conseguimos usando su propiedadDataSource:protected System.Web.UI.WebControls.Repeater provincia;…private void Page_Load(object sender, System.EventArgs e){if (!Page.IsPostBack) {DataSet dataset = newDataSet();dataset.ReadXml(MapPath(«provincias.xml»));provincia.DataSource= dataset;provincia.DataBind();}}Por ltimo, hemos de especificar cmo se visualizar cada dato delconjunto de datos en elcontrol asp:Repeater, para lo cual no nosqueda ms remedio que editar el cdigo HTMLde la pgina ASP.NET.Mediante el uso de plantillas definimos el aspecto visual denuestroconjunto de datos:158 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • CdigoNombreVisualizacin de conjuntos de datos con asp:Repeater159ASP.NET en la prcticahttp://csharp.ikor.org/
  • El resultado de la ejecucin de nuestro formulario con el controlasp:Repeater se muestraen la parte izquierda de la figura. Paraentender su funcionamiento, debemos tener en cuentalosiguiente:- La plantilla se muestra al comienzo de la salida asociadaalcontrol asp:Repeater. En este caso, lo nico que hace es crear lacabecerade la tabla.- Para cada elemento del conjunto de datos enlazado alasp:Repeater se utilizala plantilla . Esta plantilla la rellenamoscon las etiquetasHTML correspondientes a la definicin de una filade la tabla e incluimosexpresiones del tipo para visualizar losvalores que toma campo en los elementos denuestro conjunto dedatos.- Por ltimo, la plantilla se utiliza para finalizar lasalidaasociada al control asp:Repeater, que muchas veces no es msque cerrar laetiqueta con la que se abri la tabla.Obviamente, la tabla mostrada en la parte derecha de la figuraanterior es mucho ms vistosaque la sobria tabla que se visualizacon las plantillas que hemos definido para el controlasp:Repeater.Para construir una tabla de este tipo, lo nico que tenemos quehacer esdefinir la plantilla opcional . Si incluimos el cdigoHTMLnecesario para utilizar distintos colores en y podemos conseguirque las filas de la tabla se muestrencon colores alternos, como enla figura, de forma que se mejore la legibilidad de los datos yelatractivo visual de la tabla. Como su propio nombre sugiere, laplantilla determina la visualizacin de elementos alternosdelconjunto de datos. Cuando no se define, se utiliza para todosloselementos del conjunto de datos. Cuando se define, las filaspares e impares se mostrarn deforma distinta en funcin de lo quehayamos especificado en las plantillas y .Finalmente, el control asp:Repeater incluye la posibilidad deutilizar una quinta plantillaopcional: la plantilla . Estaplantilla se puede utilizar paradescribir lo que queremos queaparezca entre dos elementos del conjunto de datos.En resumen, elcontrol asp:Repeater muestra los elementos de un conjunto dedatosgenerando un fragmento de cdigo HTML a partir de lasplantillas que hayamos definido. Enel caso ms sencillo, se defineuna nica plantilla, la plantilla . En el casoms complejo, se puedenutilizar hasta cinco plantillas que se utilizarn para generar lasalidaen el siguiente orden: Header – Item – Separator -AlternatingItem -Separator – Item – … – Footer.Una de las limitaciones del control asp:Repeater es que noadmite cmodamente laimplementacin funciones de seleccin ni deedicin. Afortunadamente, en ASP.NET existen160 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • otros controles, que se pueden emplear para visualizar e inclusomodificar conjuntos de datos.En concreto, nos referimos a loscontroles System.Web.UI.WebControls.DataListySystem.Web.UI.WebControls.DataGrid que usaremos en los dosprximosapartados.El control asp:DataListEl control asp:DataList es similar a asp:Repeater, si bienincluye por defecto unatabla alrededor de los datos. Adems, sepuede disear su aspecto de forma visual desde eldiseador deformularios del Visual Studio .NET. Desde el diseador deformularios,podemos seleccionar el control asp:DataList y pincharcon el botn derecho del ratnpara acceder a las opciones de «Editarplantilla» incluidas en su men contextual. Desde ahpodemos definiruna amplia gama de propiedades del control de forma visual.El control asp:DataList, adems de las cinco plantillas que yamencionamos al hablar delcontrol asp:Repeater, incluye dosplantillas adicionales: SelectedItemTemplate yEditItemTemplate.Estas plantillas se usan, respectivamente, para resaltar elelementoseleccionado de la lista y permitir la edicin de losvalores correspondientes a uno de loselementos del conjunto dedatos.Volviendo al ejemplo de la lista de contactos, supongamos quedeseamos mostrar,simultneamente, datos relativos a varios denuestros contactos, sin tener que ir eligindolosuno a uno. Podemosusar un control de tipo asp:DataList y definir visualmenteelformato de su plantilla ItemTemplate:Edicin visual del formato correspondiente a las plantillas de uncontrolasp:DataListEn este caso, cada vez que se muestre un contacto, aparecer unaetiqueta asp:Label consu nombre acompaada de un enlaceasp:HyperLink en el que figurar su direccin decorreo electrnico.Mediante la opcin (DataBindings) que aparece en el editor de161ASP.NET en la prcticahttp://csharp.ikor.org/
  • propiedades de los controles, podemos enlazar el nombre y ladireccin de correo con loscontroles correspondientes, tal como semuestra en la figura:Manualmente, tenemos que ir seleccionando las propiedadesadecuadas de los controles,como puede ser la propiedad NavigateUrldel control asp:HyperLink, e indicar culesvan a ser los valores quese les van a asociar a dichas propiedades. En el caso de lapropiedadNavigateUrl, escribiremos algo como lo siguiente:»mailto:»+DataBinder.Eval(Container.DataItem,»Email»)Lo que hacemos visualmente desde el entorno de desarrollo setraduce internamente en unaplantilla similar a las que ya vimos alver el funcionamiento del control asp:Repeater. Alfinal, nuestrofichero .aspx contendr algo como lo siguiente:(162 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • )Igual que siempre, lo nico que nos queda por hacer es obtener unconjunto de datos yasocirselo a la lista. Por ejemplo, podramoscrear una tabla de datos a medida que contenganicamente aquellosdatos que queremos mostrar en el control asp:DataList:DataTable dt = new DataTable();DataRow dr;int i;dt.Columns.Add(new DataColumn(«Name»,typeof(string)));dt.Columns.Add(new DataColumn(«Email»,typeof(string)));for (i=0; i
  • El control asp:DataGrid es bastante ms complejo que el controlasp:DataList, sibien es cierto el entorno de desarrollo nos ayudamucho para poder disear nuestra tabla deforma visual. Para crearlas columnas de la tabla, hemos de seleccionar la opcin»Generadorde propiedades» del men contextual asociado al control.En la ventana que nos aparecepodemos definir las columnas queincluir nuestra tabla como columnas de tipo plantilla:Una vez que tenemos definidas las columnas de nuestra tabla,podemos editar las plantillasasociadas a ellas mediante la opcin»Editar plantilla» del men contextual asociado alDataGrid. En elcaso de las columnas que contienen una simple etiqueta, el procesoescompletamente anlogo al que se utiliz en la seccin anterior alusar el control DataList.Primero, se crea la plantilla en s:164 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • La propiedad Text de etiqueta que aparece en la plantilla laenlazaremos con uno de losvalores contenidos en el conjunto dedatos de la misma forma que siempre:DataBinder.Eval(Container.DataItem, «Name»)Seleccionando la opcin «Terminar edicin de plantilla» del mencontextual volvemos a lavista general de la tabla para poder editarla plantillas asociadas a las dems columnas. Unavez preparadas lasplantillas correspondientes a todas las columnas, lo nico que nosfalta porhacer es enlazar el control a un conjunto de datos(mediante su propiedad DataSource) einvocar al mtodo DataBind()para rellenar la tabla con los datos, igual que se hizo conelcontrol DataList.Antes de dar por cerrado este apartado, no obstante, veamos cmose implementan enASP.NET dos de las funciones que con ms asiduidadse repiten en aplicaciones web que hande trabajar con conjuntos dedatos: la posibilidad de seleccionar un subconjunto de los datosyla opcin de ordenar los datos de una tabla en funcin de losvalores que aparecen en unacolumna.Seleccin de subconjuntos de datosCuando queremos darle laposibilidad al usuario de que seleccione algunos de los elementosdeun conjunto de datos mostrado en una tabla, lo normal, cuandousamos aplicaciones web,es que se le aada a la tabla una columna enla que aparezca un control de tipo CheckBox:165ASP.NET en la prcticahttp://csharp.ikor.org/
  • La plantilla de la columna se crea exactamente igual quecualquier otra plantilla. En tiempo deejecucin, tal como se muestraen la siguiente figura, el control se repetir para cada una deloselementos del conjunto de datos mostrado en la tabla:Cuando queramos saber cules son los elementos del conjunto dedatos que ha seleccionado elusuario, lo nico que tendremos quehacer es acceder secuencialmente a los elementos detipoDataGridItem que componen el DataGrid en tiempo de ejecucin,tal como se muestraen el siguiente fragmento de cdigo:CheckBox cb;foreach (DataGridItem dgi in this.DataGridContacts.Items) {cb = (CheckBox) dgi.Cells[0].Controls[1];if (cb.Checked) {// Fila seleccionada}}Ordenacin por columnasOtra de las funciones que resultan bastante tiles al trabajarcon tablas es la posibilidad deordenar su contenido en funcin delos valores que aparezcan en una columna determinada.166 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • Esta funcin resulta bastante vistosa y su implementacin esprcticamente trivial en el casodel control asp:DataGrid.Aunque se puede conseguir el mismo resultado modificandodirectamente el fichero .aspxcorrespondiente a la pgina ASP.NETdonde est incluida la tabla y, de hecho, el proceso sepuederealizar a mano sin demasiada dificultad, aqu optaremos poraprovechar las facilidadesque nos ofrece el Visual Studio .NET a lahora de manipular directamente el controlasp:DataGrid desde elpropio editor de formularios web.En primer lugar, debemos asegurarnos de que nuestro controltiene habilitada la opcin»Permitir ordenar» [AllowSorting] queaparece en la pestaa «General» del generador depropiedades delDataGrid:Esto se traduce, simplemente, en la inclusin del atributoAllowSorting en el controlasp:DataGrid que aparece en el fichero.aspx:A continuacin, hemos de seleccionar las expresiones de ordenacinpara las distintascolumnas de nuestra tabla, algo que tambinpodemos hacer desde el generador depropiedades del DataGrid:167ASP.NET en la prcticahttp://csharp.ikor.org/
  • Igual que antes, la seleccin se traduce en la inclusin de unatributo: SortExpression.En este caso, el atributo aparece asociadoa las plantillas correspondientes a las distintascolumnas de latabla:…En cuanto lo hacemos, automticamente cambia el aspecto de lacabecera de la tabla. Dondeantes aparecan simples etiquetas en lascabeceras de las columnas, ahora se muestran enlacessobre los quese puede pinchar:168 Desarrollo Profesional de Aplicaciones con C#Fernando Berzal, Francisco J. Cortijo & Juan CarlosCubero
  • Lo nico que nos falta por hacer es implementar el cdigonecesario para realizar laordenacin de la tabla cuando el usuariopincha sobre los enlaces que encabezan las columnas»ordenables» dela tabla. Eso lo haremos como respuesta al evento SortCommand:private void DataGridMessages_SortCommand (objectsource,System.Web.UI.WebControls.DataGridSortCommandEventArgse){DataTable dt = (DataTable)Session[«contactTable»];DataView dv = new DataView(dt);dv.Sort = e.SortExpression;DataGridContacts.DataSource =dv;DataGridContacts.DataBind();}Lo nico que tenemos que hacer es crear una vista sobre la tablade datos y ordenarla. Unavez que tenemos los datos ordenados,enlazamos la vista al control e invocamos al mtodoDataBind para quese refresquen los datos de la tabla con los datos ordenados de lavistarecin construida.Paginacin en ASP.NETCuando los conjuntos de datos son grandes,lo normal es queslo le mostremos al usuario una parte de los datosy le demosla posibilidad de moverse por el conjunto de datoscompleto.Es lo que se conoce con el nombre de paginacin.La paginacin consiste, bsicamente, en no trabajar con msdatos delos que resulten estrictamente necesarios. En el casode lasaplicaciones web, esto se traduce en una mejora en laescalabilidadde las aplicaciones al no tener que transmitirms que aquellos datosque los que se muestran en una pginaal usuario.Como no poda ser de otra forma, el control DataGridfacilita laposibilidad de usar paginacin (sin ms que ponerla propiedadAllowPaging a true). De hecho, podemosespecificar el nmero de datosque queremos mostrar porpgina (PageSize), as como dnde y cmo tienenqueaparecer los botones que se usarn para navegar por elconjunto dedatos (PagerStyle). Cuando se cambia depgina, se produce el eventoOnPageIndexChanged, quees el que debemos interceptar para mostrarlos datosadecuados.169ASP.NET en la prcticahttp://csharp.ikor.org/
  • Formularios de manipulacin de datosAparte de mostrar datos, las aplicaciones tambin tienen quemanipularlos: realizarinserciones, actualizaciones y borrados. Portanto, a la hora de implementar la interfaz deusuario, una de lastareas ms habituales con las que ha de enfrentarse un programadores lacreacin de formularios de manipulacin de datos, tambinconocidos como formulariosCRUD porque esas son las iniciales eningls de las cuatro operaciones bsicas que realizan(creacin,lectura, actualizacin y borrado de datos). Dada su importanciaprctica, este es eltema con el que terminaremos nuestro recorridopor ASP.NET.Usualmente, los formularios de manipulacin de datos seconstruyen en torno a trese
  • Publicaciones Similares