Está en la página 1de 184

Tecnologías ASP.NET 4.0

(saltando desde la versión 2.0)

Tecnologías ASP.NET 4.0 (saltando desde la versión 2.0) José Manuel Alarcón Aguín

José Manuel Alarcón Aguín

TEcNologíAS ASP.NET 4.0 (SAlTANdo dESdE lA vErSióN 2.0) No está permitida la reproducción total o

TEcNologíAS ASP.NET 4.0 (SAlTANdo dESdE lA vErSióN 2.0)

No está permitida la reproducción total o parcial de este libro, ni su tratamiento informático, ni la transmisión de ninguna forma o por cualquier medio, ya sea electrónico, mecánico, por fotocopia, por registro u otros métodos, sin el permiso previo y por escrito de los titulares del Copyright. Diríjase a CEDRO (Centro Español de Derechos Reprográficos, www.cedro.org) si necesita fotocopiar o escanear algún fragmento de esta obra.

Derechos reservaDos © 2009, respecto a la primera edición en español, por

Krasis consulting, s. L. www.krasis.com

IsBN: 978-84-936696-1-4 Depósito Legal: VG 961-2009

Impreso en españa-Printed in spain

Agradecimientos

La tarea de escribir un libro nunca es fácil, ni para el autor ni para quienes conviven

o trabajan con él. Por eso, entre otras razones, un libro nunca es exclusivamente obra del que lo escribe.

así, debo agradecer como siempre a mi familia el que hayan aguantado mis con- testaciones secas al teléfono cuando interrumpían la escritura. eso y que no me haya pasado a verlos en unas cuantas semanas, claro.

en Krasis, si ya suele ser difícil hablar conmigo, mientras estaba con el libro ha sido poco menos que imposible. Por ello vaya mi agradecimiento también por su paciencia

a héctor, María, Pablo, verónica, Fran, Yazmín, Dani y eduardo.

a Pablo Iglesias hay que agradecerle especialmente su trabajo con las cubiertas del libro. ¡Preciosas!

el bueno de octavio hernández, un sabio de la computación y autor también de Krasis Press, revisó parte del material del libro desde la soleada california. Gracias maestro.

La gente de Microsoft Ibérica, y en especial en este caso Beatriz y David, que siempre se acuerdan de mi cuando hay algo de asP.NeT de por medio :-)

Finalmente, como siempre, a la principal sufridora de mis delirios frikis, eva. Te ρ = 1 - sin(θ)

Contenido

coNTENido

ix

PresentACión

xiii

1. ASP.NET y SuS vErSioNES

1

1.- La historia de A s P. net hasta su versión 2.0

1

2.- La versión 3.0 de .net

3

3.- La versión 3.5 de la plataforma

4

4.- Un service Pack que es mucho más que un parche

5

5.- .net 4.0 y Visual studio 2010

6

6.- De qué trata este libro (y qué deja fuera)

7

7.- en resumen

8

2. FuNdAMENToS dE AJAX

9

1.- interfaces de usuario avanzadas

10

2.- Un poco de teoría: el objeto XMLHttp request

11

3.- Basta de teoría: vamos a la práctica

13

4.- Problemas típicos de Ajax y sus soluciones

16

4.1.- Llamadas fuera de dominio

16

4.2.- Gestión de errores y llamadas que no vuelven

17

4.3.- envío de datos al servidor

18

4.4.- Contenidos no actualizados debido a cachés

20

5.- Devolución de información: JsOn

21

6.- en resumen

23

3. ASP.NET AJAX EN El SErvidor

25

1.- Un primer ejemplo: mejora de una aplicación básica con AJAX

26

2.- Postbacks parciales y repintados parciales de página

30

3.- el control scriptManager

31

4.- el control UpdatePanel

32

5.- Modos de actualización parcial

33

6.-

Disparadores

34

7.- indicación de progreso de las llamadas asíncronas

37

8.- refrescos parciales periódicos

40

9.- Unicidad del scriptManager

42

10.- el control scriptManagerProxy

43

11.- Gestión de errores AJAX

43

12.- incompatibilidades de AJAX

48

13.- AJAX Control toolkit

50

4. ASP.NET AJAX EN El NAvEgAdor

59

1.- retrollamadas de red a métodos estáticos

60

x

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

1.1.- Análisis de tráfico con un UpdatePanel

61

1.2.- ejemplo optimizado con retrollamadas de red a métodos estáticos

63

2.- Llamadas a servicios Web

67

2.1.- Definición de un servicio Web AsMX para ser llamado desde Javascript

68

2.2- Creación de la página cliente para llamar al servicio

71

3.- servicios de aplicación: Membership y roles desde el navegador

75

4.- referencias a scripts en páginas y controles

81

5.- Optimización de uso de bibliotecas en A s P. net 4.0

84

5.1.- Combinación de scripts

87

6.- en resumen

88

5. EN l AZAdo A dAToS EN E l NAvEgAdor

89

1.- Concepto de plantillas de lado cliente

91

2.- Las bases para trabajar

93

3.- Definición de la plantilla de productos

94

4.- La clase DataView

95

5.- Pseudo-columnas y atributos especiales

98

6.- Atributos sys condicionales

100

7.- Atributos code para renderizado condicional

101

8.- enlazado de datos en tiempo real

103

9.- Vistas maestro-detalle: preparar el maestro

105

10.- Vistas maestrro-detalle: preparar los detalles

106

11.- Devolver los datos modificados al servidor: contextos de datos

108

12.- La definición del método de guardado de cambios

110

13.- Historia del navegador

112

14.- en resumen

115

6. ASP.NET dyNAMic dATA: iNTE rFAcES dE dAToS A l A vElocidAd dE lA luZ

117

1.- ¿Qué es Dynamic Data?

118

2.- nuestro primer proyecto con Dynamic Data

119

3.- Definir el modelo de datos

121

4.- Añadiendo el modelo a Dynamic Data

122

5.- Plantillas de interfaz de usuario

124

5.1.- Diseccionando una plantilla

125

6.- Plantillas para entidades

129

7.- Plantillas para campos

129

8.- Las rutas de las páginas dinámicas

132

8.1.- Parámetros individuales en las rutas

135

9.- Ampliando los metadatos del modelo

136

9.1.- Mejorando la validación de campos

138

9.2.- Validaciones personalizadas

140

10.- Plantillas de campos propias

141

11.- Dynamic Data en páginas propias

143

12.- en resumen

146

Contenido

xi

7. FilTr Ado dE dAToS AuToMÁTico coN QuEryEXTENdEr

147

1.- el control Queryextender

147

2.- tipos de filtros

148

3.- Creación de la página base para ejemplo

149

4.- Primer filtro: búsqueda por nombre

152

5.- Filtrado por rangos de valores

154

6.- Filtrado por valores de propiedades

154

7.- Parámetros de filtrado

155

8.- en resumen

157

íNdicE ANAlíTico

159

Presentación

en los últimos años la World Wide Web ha evolucionado mucho. existe un verdadero abismo tecnológico y conceptual entre aquellas primeras páginas estáticas —con cuatro etiquetas para dar formato y unos pocos enlaces— y las actuales aplicaciones Web 2.0 como Google Docs, Facebook o Live Maps. hay tanta diferencia entre ellas como entre los carruajes tirados por caballos y un Fórmula 1. el mundo de mediados de los 90 tampoco era el mismo y, desde los 70 millones

de internautas estimados entonces a los casi 1.600 millones de 2009 (InternetWorld-

stats.com), la cosa ha cambiado mucho. Las diferencias estriban no sólo en lo que salta a la vista, sino también en lo que no se ve. Las expectativas de los usuarios no son los mismas, los lenguajes de

programación tampoco. antes era suficiente con mostrar texto plano y unos gráficos, hoy es preciso habilitar una interactividad total entre los elementos de la pantalla y el usuario. cuando todos accedíamos a la WWW usando módems de 28.8 Kbps era acep- table esperar más de un minuto para recibir el contenido estático de una página.

Y dábamos gracias a los dioses por ello ;-) hoy en día no sólo debe haber una

respuesta inmediata, sino que lo normal es que ni siquiera se evidencie en modo alguno que ha habido un viaje al servidor. Las fronteras entre las aplicaciones de escritorio y las aplicaciones Web son cada vez más difusas. ¡Bienvenidos al mundo

de aJaX y las rIa (Rich Internet Applications)! asP.NeT es sin duda (y no es una opinión, sino un hecho) la plataforma de

creación de aplicaciones Web más productiva que existe. La base fundamental sobre

la que se sustenta esta tecnología y las diferentes características que ofrece, hacen

posible esta visión moderna, interactiva y escalable de la red. este libro trata precisamente de esas tecnologías especializadas que marcan la diferencia entre una aplicación Web corriente y otra de la era Web 2.0 y más allá. asP.NeT 4.0 y visual studio 2010 nos traen las últimas mejoras de esta plata- forma de desarrollo.

¿A quién va dirigido este libro?

Por lo que acabo de comentar el lector ya se dará cuenta de una cuestión importante:

este libro no es para principiantes. el contenido va dirigido a programadores de asP.NeT 2.0 que quieren dominar las principales tecnologías que aporta la última edición, asP.NeT 4.0. se da por hecho que el lector tiene unos conocimientos, cuando menos fundamentales, de esta plataforma. ahora bien, no se da por sentado nada en cuanto a las técnicas que se explican en el interior, de las que se parte de cero para facilitar el aprendizaje.

xiv

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

es especialmente interesante que el lector conozca un poco el leguaje Javascript

y una pizca de hTML, pues la tecnología aJaX se sustenta sobre ellos y vendrá bien para comprender el código de ejemplo.

¿Qué temas se tratan en el libro?

Una gran parte del contenido se dedica a aJaX y todas las técnicas que hacen que funcione. Pero no te confundas, este no es el típico libro de aJaX que has visto por ahí. va mucho más allá del uso del UpdatePanel que todo el mundo conoce, para adentrarse en la optimización para conseguir aplicaciones escalables. Un primer capítulo se dedica a enseñar los fundamentos de aJaX sin el apoyo de bibliotecas especializadas. Para que nos entendamos mejor: aJaX “a pelo”. esto te ayudará a comprender bien su funcionamiento primordial y podrás responder mejor ante problemas que surjan más adelante en aplicaciones reales apoyadas en código de otros. asP.NeT aJaX es la biblioteca de Microsoft para crear páginas aJaX. el se- gundo capítulo presenta esta tecnología para sacarle partido sin tener que salirse de las técnicas habituales de todo programador .N eT. aprenderás a utilizar bien

sus controles de servidor, que ofrecen una grandísima productividad con un rápido aprendizaje. Te proporcionará grandes ventajas y la usarás mucho, pero no está exen-

ta de problemas. Todo programador preocupado por el rendimiento y la escalabilidad

de sus aplicaciones debe ir más allá y no quedarse en este punto. Por eso, el tercer capítulo se centra en las capacidades del lado de cliente de asP.NeT aJaX. se presenta la tendencia actual de las aplicaciones Web a trasladar cada vez más procesamiento al navegador, intercambiado datos directamente con el servidor. aprenderemos lo necesario para poner en práctica esta visión, exponiendo

y recibiendo datos a través de servicios que se consumen desde el navegador con

Javascript y el apoyo de asP.NeT aJaX. en la cuarta parte del libro llevaremos el concepto de aJaX “puro” al extre- mo gracias a las nuevas funcionalidades de plantillas para el lado cliente que nos ofrece asP.NeT 4.0. esta nueva tecnología abre las puertas a un desarrollo Web super-eficiente que traslada toda la generación de la interfaz de usuario al navegador, dejando el servidor como un intermediario para mover datos. el quinto capítulo se centra en la nueva tecnología de generación de interfaces de gestión de datos: Dynamic Data. Gracias a ella podemos conseguir en minutos completas interfaces de administración de bases de datos para crear los típicos “Mantenimientos”. Pero como veremos, la tecnología va mucho más allá, propor- cionándonos total flexibilidad para hacer lo que queramos en la gestión de datos sin apenas escribir código. Tendrás a tu alcance un nuevo nivel en la escala de la de productividad. La última parte del libro se centra en explicar un conjunto de controles Web destinados a crear interfaces para filtrado de datos. se trata de los QueryExtender

Presentación

xv

y las clases relacionadas con éstos. con ellos, nuevos en asP.NeT 4.0, es muy sen- cillo conseguir avanzados sistemas de filtrado de información sin tener que escribir código. combinándolos con los controles enlazados a datos podemos crear complejas páginas con listados de información en minutos.

las herramientas que necesitas para trabajar

hace poco, después de una charla que impartí, tuve la oportunidad de hablar un buen rato con un par de emprendedores del mundo TIc que se me acercaron. Tras un tiempo de experiencia laboral por cuenta ajena decidieron volar solos, y un par de meses antes habían constituido una empresa para desarrollar aplicaciones Web. Me dijeron que se habían decidido a trabajar con PhP en lugar de con asP.NeT por que “en PhP es todo gratis y para programar con asP.NeT necesitamos pagar licencias a Microsoft.”. ¡Qué confundidos estaban! Y no sólo en esta afirmación, sino con otros muchos mitos y leyendas equivocados que existen sobre asP.NeT y sobre lo que algún día tengo que escribir largo y tendido. Menos mal que dieron conmigo para sacarlos de su error ;-) Para desarrollar con asP.NeT, tanto aplicaciones comerciales como para cual- quier otro uso, no es necesario pagar ni un solo euro a Microsoft. visual studio dispone de unas ediciones especiales llamadas Visual Studio Express Edition que son gratuitas y de libre descarga. apenas tienen limitaciones para desarrollar y en concreto la versión especial para desarrollo Web, Visual Web Developer Express, tiene toda la funcionalidad disponible en esta versión gratuita. Para la parte de desarrollo de bases de datos Microsoft ofrece también una versión express de su gestor: SQL Server Express. sus limitaciones son que sólo le está permitido ocupar 1 GB de raM para caché de datos, utilizar un único procesador de la máquina (con los núcleos que tenga éste, da igual) y el tamaño máximo de las bases de datos que puede manejar la licencia es de 4 GB. son unas limitaciones bas- tante amplias y es difícil llegar a superarlas en aplicaciones comunes en la PYMe. ofrece herramientas adicionales de administración y de reporting entre otras, y es perfecta para cualquier aplicación de gestión o para Internet. Y por supuesto sigue siendo gratis aunque nuestras aplicaciones sean comerciales. Las últimas versiones de Visual Web Developer Express y de SQL Server Express se pueden descargar libremente desde http://www.microsoft.com/express/. Te las recomiendo para practicar las explicaciones del libro. si quieres funcionalidades de trabajo en equipo, desarrollar para office o para móviles o poder depurar aplicaciones en remoto, puedes actualizarte a las ediciones comerciales de visual studio. Toda la información aquí: http://www.microsoft.com/ visualstudio/. Para aplicaciones empresariales de gran tamaño están disponibles las otras ediciones comerciales de sQL server. consulta sus características en http://www. microsoft.com/sqlserver/.

xvi

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

El código fuente de ejemplo

Todos los ejemplos y demos desarrollados en el libro se pueden descargar desde la web de la editorial. visita www.krasispress.com y busca el libro en el catálogo, bien navegando por las categorías o con la caja de búsqueda. en la ficha del libro existe un enlace para descargar los ejemplos de código. Descárgate el archivo en formato ZIP y descomprímelo en cualquier carpeta de tu ordenador. Para abrir los ejemplos desde visual studio lo mejor es usar la opción Archivo·Abrir·Sitio Web y elegir la carpeta del ejemplo en el que tengas interés. Por el nombre se deduce fácilmente a qué parte del libro corresponden. Para los ejemplos que usan datos he empleado la archiconocida base de datos Northwind. La puedes descargar en diversos formatos desde el sitio de descargas de Microsoft. vete a http://download.microsoft.com y una vez allí introduce la palabra “Northwind” en el cuadro de búsqueda:

la palabra “Northwind” en el cuadro de búsqueda: Figura 1.- descarga de la base de datos

Figura 1.- descarga de la base de datos Northwind

se trata de una base de datos muy antigua, por eso pone que es una descarga para sQL server 2000, pero no te preocupes pues te funcionará bien con cualquier

versión moderna del gestor de datos. La he usado porque es la más popular entre los programadores de .NeT, y hay una alta probabilidad de que la conozcas ya. existe una versión nueva de esta base de datos, creada por la comunidad, que puedes descargar desde http://www.codeplex.com/NorthwindCommunity/. es un

de actualizar un poco el ejemplo original, pero no te

proyecto reciente que trata

aseguro que los cambios que hayan hecho vayan a funcionar con los ejemplos del libro, así que lo dejo a tu criterio, pero puedes probar.

Presentación

xvii

contacto con el autor y la editorial

Puedes encontrarme y contactar conmigo a través de mi blog sobre desarrollo Web

en www.jasoft.org. ahí publico constantemente todo tipo de consejos, noticias y vídeos sobre el desarrollo para Internet con asP.N eT. Te recomiendo que lo visites. Me encanta recibir comentarios y críticas constructivas, pero no me gustan los que sólo se acuerdan de mi cuando necesitan algo “¿capisce?” ;-) La web de la editorial es www.krasispress.com. Desde allí puedes ponerte en contacto con el equipo editorial cuando quieras. Dentro de Krasis existe el proyecto campusMvP (www.campusmvp.com) del que probablemente hayas oído hablar. se trata de formación on-line con cursos creados

y tutelados por conocidos MvP de Microsoft, para que tú y tu equipo os forméis a

vuestro ritmo y desde cualquier lugar preguntándole a los que más saben. en cam- pusMvP tenemos un boletín mensual de noticias, trucos y “frikadas” varias que tiene

varios miles de suscriptores encantados de recibirlo. Te recomiendo que te suscribas. También hemos puesto en marcha una página en Facebook (http://go.krasis.com/Fa- cebook) con actualizaciones frecuentes sobre el mundo Microsoft y sus tecnologías, enlaces a artículos interesantes, noticias, vídeos prácticos, ofertas exclusivas para

“fans”, etc

si estás en esta red social no olvides hacerte fan de la página.

¡comencemos!

Gracias por tu interés en este libro. espero que el esfuerzo de escribirlo haya valido

la pena y que tras haberlo leído estés en condiciones de crear aplicaciones Web de alta

calidad, escalables y sacando todo el partido a las últimas tecnologías Microsoft.

cAPíTulo 1
cAPíTulo
1

A s P. net y sus versiones

¿Por qué comenzar un libro que no está dirigido a principiantes con una cuestión,

en apariencia, tan insignificante como ésta?

en absoluto. como veremos, en asP.NeT los saltos en la numeración de las versiones no se corresponden en realidad con los cambios cuantitativos que cabría esperar de éstos, lo que causa gran confusión entre los programadores. Dada la cantidad de caracte- rísticas existentes en esta potente plataforma de desarrollo Web, es muy importante saber qué hay disponible en cada versión, e incluso en cada actualización dentro de una versión. Por ello vamos a hacer una composición de lugar antes de ponernos a trabajar.

Pues porque no es un asunto trivial

1.- lA hiSToriA dE ASP.NET hASTA Su vErSióN 2.0

La primera versión de asP.NeT, la 1.0, apareció en el mercado en enero de 2002, junto con la edición inicial de visual studio para la plataforma .NeT. a ntes de este lanzamiento oficial, hubo diversas Betas en las que aún la tecnología llevaba el nombre de asP+. Éstas estuvieron disponibles para experimentar desde mediados de 2000, por lo que en realidad la plataforma tiene mucho más recorrido del que se desprende de las fechas oficiales. La idea era sustituir al asP 3.0 clásico -por eso le dejaron un nombre parecido, aunque no tengan nada que ver- y ofrecer un entorno de desarrollo para el servidor con grandes ventajas sobre lo existente en el mercado. Un punto importante era tratar de ofrecer los mismos paradigmas de desarrollo que las tradicionales aplica- ciones de escritorio, pero aplicados a la Web. esto implicaba sobre todo orientación a eventos y a objetos, uso de lenguajes compilados, independencia automática del navegador y productividad, mucha productividad. con asP.NeT se empezaron a desdibujar los límites entre cliente y servidor en el desarrollo Web.

2

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

Nota:

obviamente sin olvidarnos del inexcusable hecho de que hay una red de comunicaciones de por medio, con lo que ello implica en cuanto a transferencia de datos y velocidad, lo cual sigue siendo muy importante, claro.

el nuevo paradigma de desarrollo traído por los WebForms y la técnica de Postback, realmente innovador y tan característico de asP.NeT, hizo que desarrollar un formulario Web no fuese demasiado diferente de hacerlo para una aplicación de escritorio. Todas las características de productividad de esta primera versión con- virtieron rápidamente a asP.NeT en una plataforma muy popular, pues permitía a los desarrolladores conseguir resultados impresionantes con muy poco tiempo y esfuerzo. en abril de 2002, poco después de un año, Microsoft actualizó mínimamente la plataforma sacando asP.NeT 1.1 y visual studio .NeT 2003. en esta ocasión se incorporaron los controles móviles para el desarrollo Web orientado a PDa y teléfonos móviles, así como la validación automática de los elementos de la interfaz de usuario. Una actualización menor. el verdadero punto de inflexión en lo que se refiere al ámbito de desarrollo Web llegó en noviembre de 2005 (febrero de 2006 en españa). en esta fecha se lanza ASP.NET 2.0 junto con visual studio 2005. este sí que constituyó un cambio revolucionario dentro de asP.NeT; uno que influiría definitivamente en todas las versiones posteriores. con todo el feedback recibido por Microsoft durante los cinco años previos, el equipo de desarrollo le dio un vuelco completo a la plataforma. se introdujeron tantos cambios y características que se necesita un libro entero 1 para explicarlas. Las más relevantes son las siguientes:

Nuevo modelo de compilación y separación de código e interfaz, que es un cambio de los propios fundamentos de trabajo de la plataforma.

Precompilación y despliegue de sitios Web para obtener un máximo ren- dimiento desde el primer momento. soporte de sistemas de 64 bits.

el modelo de proveedores, con sus implicaciones en cuanto a extensibilidad de la plataforma.

acceso a datos, incluso en varias capas soa, sin necesidad de escribir có- digo, gracias a un modelo declarativo.

controles enlazados a datos de gran potencia, como las nuevas y mejoradas rejillas GridView, y controles de visualización y edición integrada como FormView o DetailsView.

1 el autor de este libro ha escrito también otra obra dedicada a explicar con detalle todas las tec- nologías de asP.NeT 2.0, y que se puede adquirir en www.krasispress.com.

A s P. net y sus versiones

3

Independencia de la interfaz de las páginas de su maquetado (Master Pages) y de su aspecto (Temas y Skins), fomentando la separación más absoluta entre interfaz y funcionalidad.

Interfaces de usuario para control de la seguridad mediante controles de arrastrar y soltar. Puedes construir toda la seguridad de tu aplicación sin escribir código alguno.

creación de portales personalizables mediante WebParts.

Infraestructura de instrumentalización y monitorización de aplicaciones.

Nuevas técnicas de localización y globalización de aplicaciones.

Páginas asíncronas para sitios altamente escalables.

controles de navegación.

servicios de personalización de preferencias de usuario.

este salto a la madurez de la plataforma abrió un nuevo mundo de posibilidades de desarrollo con alta productividad para sistemas Web empresariales, pero hizo que todos los programadores de la versión anterior tuvieran que actualizar sus co- nocimientos. La cuestión más importante, llegados a este punto, es señalar que el núcleo de ASP.NET es exactamente este mismo, el 2.0, en el resto de versiones que han salido desde entonces. esto tiene una transcendencia fundamental, porque podemos afirmar que si conoces bien ASP.NET 2.0 conoces todo lo necesario para sacarle partido a las siguientes versiones, porque en esencia son la misma, como enseguida veremos. sin embargo, si provienes de la versión 1.x tendrás que aprenderlo todo casi desde cero.

2.- lA vErSióN 3.0 dE .NET

La versión 3.0 de la plataforma .NeT se presentó en sociedad en noviembre de 2006, justo un año después de la anterior. en realidad, esta versión 3.0 no era otra cosa que la plataforma .NeT 2.0 junto con cuatro nuevas aPI especializadas que estaban construidas sobre ésta:

Windows Communication Foundation (WCF): para la creación de sis- temas distribuidos basados en conceptos soa (arquitecturas orientadas a servicios). a pesar de lo que pueda parecer por el poco afortunado nombre —que confunde a algunos desarrolladores—, estos servicios no están atados en absoluto a la plataforma Windows, sino que siguen los estándares de la W3c y pueden interoperar con cualquier otro sistema operativo y lenguaje de programación.

Windows Workflow Foundation (WF): que permite el desarrollo de sis- temas adaptables basados en flujos de trabajo tanto secuenciales como de estado, persistentes en el tiempo y con otros servicios añadidos.

4

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

Windows Presentation Foundation (WPF): la nueva aPI para creación de interfaces de usuario vectoriales avanzadas. va mucho más allá de los sistemas tradicionales de ventanas para ofrecer un paradigma mixto entre el escritorio y la Web. Un subconjunto de WPF, multiplataforma y específico para la Web, es lo que se conoce como Silverlight.

Windows CardSpace: un sistema cliente para la gestión de identidades en Internet y en la empresa. es, con diferencia, la aPI de la versión 3.0 que menos adopción ha tenido.

si bien todas estas aPI adicionales son muy importantes y abren muchas vías de mejora en la programación de sistemas empresariales, lo cierto es que no dejan de ser añadidos a la plataforma, que dependen de ésta, pero el núcleo sigue siendo la versión 2.0 sin cambios de ningún tipo. en lo que respecta al desarrollo Web y asP.NeT, la versión 3.0 no aporta carac- terística nueva alguna. obviamente, podemos sacarle partido a alguna de estas aPI para añadir características a nuestras aplicaciones Web (por ejemplo, un servicio Web creado con WPF o un flujo de decisión basado en WF), pero en lo que se refiere a la plataforma asP.NeT, en ese momento sigue siendo la misma que había un año atrás.

3.- lA vErSióN 3.5 dE lA PlATAForMA

Mientras tanto, el mundo de las aplicaciones Web empieza a ver la invasión de AJAX. estos desarrollos, a los que dedicamos una gran parte de este libro, se basan en la interacción estrecha con el usuario desde la interfaz del navegador, aparentando en la medida de lo posible que no hay comunicación visible con el servidor. La idea es que las aplicaciones Web se parezcan más aún a las de escritorio, sin recargas de páginas y dando la sensación de que todo ocurre en el equipo del usuario. Microsoft no puede permanecer ajena a esta tendencia que ellos mismos habían creado (como se explica en el primer capítulo de aJaX), así que en enero de 2007 aparece una aPI de manera independiente al desarrollo de la línea principal de .N eT: ASP.NET AJAX, por aquel entonces conocida con el nombre en código de “atlas”. esta aPI para crear interfaces web de alta velocidad de respuesta y sin recarga de páginas, es un éxito instantáneo y se puede instalar paralelamente a asP.NeT trabajando sobre la versión 2.0 existente y con visual studio 2005. Unos meses después, en noviembre de 2007, aparece visual studio 2008, que incluye la versión 3.5 de la plataforma .NeT. esta versión sí que contiene cambios sustanciales en los lenguajes c# y vB y en los correspondientes compiladores. La mayor parte de dichos cambios tienen que ver con añadidos para dar soporte al nuevo lenguaje integrado de consultas LINQ (Language INtegrated Queries). es decir, el núcleo de la plataforma sigue siendo el mismo (versión 2.0), pero con modificaciones en los lenguajes y algunas aPI añadidas, en especial las relacionadas con LINQ.

A s P. net y sus versiones

5

Para acabar de liar las cosas, aunque la versión de la plataforma es la 3.5, la de los lenguajes no coincide. Por ejemplo, la versión de c# aparecida entonces es la 3.0, lo que añade más confusión para los programadores. en este momento se incorpora oficialmente el soporte para aJaX a la parte de desarrollo Web, por lo que a partir de entonces podías contar con que la plataforma tendría incorporado aJaX sin necesidad de instalarlo de manera separada. además, para dar soporte a LINQ desde aplicaciones Web se añadió una biblioteca llamada System.Web.Extensions.dll que incluía tres nuevos controles: LinqDataSource, ListView y DataPager. Por lo tanto, lo que se dio en llamar asP.NeT 3.5 era en realidad lo siguiente:

asP.NeT 2.0 + asP.NeT aJaX + 3 controles

De nuevo importantes mejoras globales, gracias a LINQ para el acceso a datos, pero el mismo núcleo en lo que al desarrollo Web respecta. La interfaz de trabajo de visual studio 2008 ofrece también algunas características nuevas de productividad para la Web, sobre todo el soporte de Intellisense y depuración para el lenguaje Javascript.

4.- uN Service Pack QuE ES Mucho MÁS QuE uN PArchE

¿Qué tendrá de especial el mes de noviembre para Microsoft? No lo sé, pero si te has fijado, es el mes en el que desde hace muchos años salen todas las grandes versiones de sus plataformas de desarrollo :-). Así, en noviembre de 2008 (como no podía ser de otra manera) aparece el Service Pack 1 para .NET 3.5, es decir, la nueva versión de la plataforma: .NET 3.5 SP1. Tradicionalmente, los Service Pack están pensados para agrupar en una sola des- carga una recopilación de ajustes, resoluciones de fallos y parches de seguridad con el objeto de facilitar su aplicación a los usuarios. En realidad no deberían incluir nuevas funcionalidades. Incluso la propia Microsoft los define de esta manera: http:// support.microsoft.com/sp. Pero lo cierto es que en diversas ocasiones el gigante de Redmond los ha utilizado para agregar grandes bloques de funcionalidad a algunos productos. Este fue el caso del SP1 para .NET 3.5. En esta actualización, Microsoft incluyó novedades en todos los ámbitos, siendo la más visible de todas ellas la aparición de Entity Framework, su nuevo ORM para acceso a datos. en el ámbito del desarrollo Web aparecieron también varias características, aun- que todas se sustentaban sobre asP.NeT 2.0. entre ellas se encontraban:

Dynamic Data: un nuevo sistema de creación automática de interfaces de usuario Web a partir de modelos de datos.

Control EntityDataSource: para dar soporte a acceso a datos declarativo a través de Entity Framework.

6

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

ADO.NET Data Services: creación y exposición automática de servicios Web para acceso a datos en modo resT, fundamentalmente basándose en Entity Framework.

Enrutamiento: soporte para definición dinámica de rutas virtuales en el servidor y su mapeado a archivos existentes o no. Especialmente pensado para dar soporte a ASP.NET MVC, del que hablaré en breve. Muy sencillo de utilizar. Toda la información aquí: http://msdn.microsoft.com/es-es/library/

cc668201.aspx.

Mejoras en AJAX: en concreto, soporte para el historial del navegador, un sistema de combinación de scripts para mejorar los tiempos de descarga de estos archivos, y un control para mostrar vídeos.

No está mal para un simple parche.

5.- .NET 4.0 y viSuAl STudio 2010

Y por fin llegamos al final de la historia (por el momento). a finales de 2009 hacen

su aparición visual studio 2010 y la versión 4.0 de la plataforma.

en lo que se refiere a visual studio, los cambios son sustanciales. Para empezar,

el entorno es completamente nuevo y está basado en WPF, con interesantes mejoras

para la escritura de código, la depuración y las superficies de diseño. en lo que se refiere al núcleo de la plataforma y las aPI relacionadas, hay mu-

chos perfeccionamientos y añadidos, si bien los más importantes, en mi opinión, tienen que ver con la introducción de soporte en la plataforma para el desarrollo paralelo. en la actualidad se han popularizado los sistemas con más de un procesador

y, sobre todo, los que llevan procesadores de múltiples núcleos (conocidos como

manycore), que son hoy el estándar de la industria y que se incluyen hasta en los

portátiles de gama más baja. estos sistemas abren grandes posibilidades para el desarrollo de aplicaciones más eficientes y de mayor rendimiento, sacando partido

a la capacidad de ejecutar en paralelo múltiples hilos de trabajo. el desarrollo de aplicaciones con múltiples hilos, sin embargo, reviste una gran complejidad para

el programador, y con frecuencia se da la paradoja de que aplicaciones con multi-

subproceso se ejecutan peor en sistemas manycore que en sistemas sencillos más antiguos. Gracias a las extensiones para el desarrollo paralelo incluidas en .NeT 4.0, la creación de este tipo de aplicaciones asíncronas y multi-subproceso se simplifica en gran medida. el nuevo modelo permite a los desarrolladores la escritura de código paralelo que es eficiente, granular y escalable, pero sin tener que lidiar directamente con las dificultades de la creación y sincronización de hilos, y además usando un lenguaje más natural para el programador.

A s P. net y sus versiones

7

otra importante novedad es el soporte para lenguajes dinámicos, del estilo de Lisp, Ph P, ruby o incluso Java script, que ahora son mucho más fáciles de incorporar

a la plataforma. en lo que respecta a la parte de desarrollo Web, la principal novedad es, sin duda, el nuevo sistema de plantillas enlazadas a datos en el navegador, parte de la nueva versión de asP.NeT aJaX. esta característica abre la posibilidad de crear aplicaciones aJaX más “puras” con gran trasvase de funciones desde el servidor al cliente. Las plantillas de lado cliente se tratan con profundidad en esta obra. También se ha añadido un nuevo control Chart para generar gráficos, y ciertas mejoras en Dynamic Data. estas últimas también las estudiaremos. adicionalmente, asP.NeT 4.0 incluye una nueva tecnología de desarrollo Web llamada ASP.NET MVC, que se basa en el patrón de diseño Modelo vista-con- trolador (de ahí el nombre). Éste constituye un sistema de desarrollo Web paralelo al asP.NeT tradicional, usando otro tipo de paradigmas completamente diferentes. esta tecnología ha surgido como un proyecto independiente y ahora se incorpora con pleno soporte a la plataforma en la versión 4.0. hay quien la adora y le ve grandes ventajas, y hay quien opina que es un paso atrás en el modo de desarrollar aplica- ciones Web. en cualquier caso, se trata de una tecnología para el desarrollo Web completamente aparte de la tradicional y que en cierta medida “va por su cuenta”. Por este motivo en este libro, centrado en el desarrollo asP.NeT tradicional, no se incluye asP.NeT Mvc. existen en .NeT 4.0 otros muchos otros añadidos y mejoras de diverso calado, muchos de los cuales provienen del sP1 para .NeT 3.5 y que se han incorporado ya como base a la plataforma. en http://tinyurl.com/PDC2008-NETFX4PDF hay para descarga un poster de alta resolución que permite ver todas las novedades de .NeT 4.0 en cada una de sus áreas de una forma resumida y sencilla.

6.- dE Qué TrATA ESTE libro (y Qué dEJA FuErA)

como hemos podido comprobar en esta breve historia de .NeT, existe una cierta complejidad para entender sus versiones y lo que nos proporciona cada una de ellas. Lo que sí podemos afirmar es que, en lo que respecta al desarrollo Web, todas las recientes se sustentan en la funcionalidad proporcionada por la 2.0. Las versiones

3.0, 3.5, 3.5 sP1 y 4.0 incluyen añadidos y mejoras que trabajan con 2.0 por debajo

y aportan funcionalidades específicas, como el trabajo asíncrono desde el cliente o

la creación de interfaces automatizadas. Por ello, este libro se va a centrar en las principales tecnologías aparecidas des- de la versión 2.0 de asP.NeT y hasta la versión actual, que las contiene a todas. así, centraremos gran parte de la obra en el desarrollo de aplicaciones AJAX, empezando por los fundamentos de esta tecnología, la creación de aplicaciones aJaX basadas en el servidor (que es la más común pero la menos óptima) y por fin, el cambio de filosofía que supone transferir gran parte de la lógica desde el servidor al cliente, que es la parte más compleja (y también la más interesante).

8

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

con ello abarcaremos todo lo que es necesario saber de asP.NeT aJaX, desde

la versión descargable independientemente para .NeT 2.0 hasta las novedades apa-

recidas con .NeT 3.5 sP1 y las últimas técnicas avanzadas de asP.NeT 4.0, por lo

que se tendrá una referencia muy completa. otra tecnología que no podíamos dejar fuera es Dynamic Data. aparecida en .NeT 3.5 sP1, es casi una desconocida para la gran mayoría de los programadores

Web. esto es una verdadera lástima, pues esta tecnología ofrece grandes posibilidades

y mejoras de productividad. con asP.NeT 4.0 se han incluido algunos perfeccio-

namientos adicionales y se espera que empiece a utilizarse de manera generalizada. en este libro aprenderás lo necesario para sacarle todo el partido. Para terminar he incluido también un completo capítulo sobre los nuevos contro- les para generación de interfaces de filtrado. existen otras pequeñas mejoras de menor calado que han aparecido con asP.NeT 4.0 para la parte de desarrollo Web. No las he incluido aquí pues son una amalgama

de diferentes cosas no relacionadas y hay información exhaustiva en Internet sobre ellas. en mi blog (www.jasoft.org) podrás encontrar información sobre la mayoría en diversas entradas que he ido añadiendo y añadiré en el futuro. hay muchas otras tecnologías que se pueden utilizar en los desarrollos para Internet con .NeT, pero que no son específicas para este propósito: LINQ, Enti- ty Framework, Windows Communication Foundation, Silverlight/WPF, Workflow

cualquiera de ellas es lo suficientemente extensa y compleja como

para merecer un libro dedicado, por lo que no tiene sentido incluirlas en esta obra.

Foundation

si tienes interés en aprender estas tecnologías te recomiendo que visites www.cam- pusmvp.com, en donde encontrarás los mejores libros y cursos del mercado sobre todas ellas.

7.- EN rESuMEN

Una vez que sabemos ubicarnos entre la maraña de versiones y tecnologías para el desarrollo Web, ya estamos en condiciones de comenzar a aprender las principales características de las últimas versiones de asP.NeT. ¡comencemos!

cAPíTulo 2
cAPíTulo
2

Fundamentos de AJAX

Desde sus comienzos y hasta hace relativamente poco tiempo las interfaces de usua- rio de las aplicaciones Web han sido más o menos siempre iguales. Las limitaciones propias del protocolo hTTP (Hyper Text Transfer Protocol) utilizado en las páginas Web han impuesto el tradicional modelo de “petición-respuesta-procesado en el navegador” (a partir de ahora PRP) y vuelta a empezar. Los pasos que sigue una aplicación Web corriente para funcionar suelen ser los siguientes:

1. el usuario solicita una página

2. el servidor devuelve el contenido hTML correspondiente a ésta, normal- mente generado a partir de alguna tecnología de servidor (como asP.NeT o PhP)

3. el navegador recibe este hTML, lo procesa y visualiza el contenido resul- tante.

4. el usuario interactúa con el hTML, envía un formulario al servidor o pulsa un enlace, y se repite el ciclo desde el paso 1: se solicita la página, se de- vuelve su contenido, se procesa y se visualiza.

este proceso es el más natural para hTTP —pensado desde luego para fun- cionar así— pero tiene el problema de que para obtener una página prácticamente igual a la inicial pero con pequeñas modificaciones es necesario recargar la página completa. esta situación es especialmente común desde que asP.NeT apareció en escena hace ya unos cuantos años, con su novedoso sistema de “postback”. Gracias a este concepto una aplicación Web se programa prácticamente igual que una de escritorio, respondiendo a eventos y accediendo directamente a las propiedades de los objetos. el problema del sistema es que cada uno de los postback al servidor hace que se recargue la página completa, lo cual es percibido de manera evidente por los usuarios (es decir “se nota” el refresco de la página) y crea una sensación poco amigable. además si el retorno de la página tarda más que unos pocos milisegundos se pierde capacidad de respuesta de la página puesto que, durante el proceso de petición-respuesta-procesado, la interfaz del navegador no responde.

10

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

si bien el concepto de “postback” es extremadamente útil, las actuales tendencias en el desarrollo Web hacen que éstas sean cada vez más parecidas a aplicaciones de escritorio. esto implica que los molestos y a la vez inevitables viajes al servidor no deberían ser percibidos por los usuarios. La sensación para éstos debe ser la de que la aplicación está todo el tiempo en su equipo, dejando de lado al servidor, como en una aplicación de escritorio tradicional.

1.- iNTErFAcES dE uSuArio AvANZAdAS

si has usado alguna vez Facebook, hotmail, GMail o alguna aplicación web de última hornada sabes perfectamente de qué estoy hablando. Toma por ejemplo el caso de Facebook. cuando actualizas tu estado o introduces un comentario para un amigo, por detrás se está ejecutando el proceso PrP antes descrito, sólo que tú no lo notas ya que se realiza de manera asíncrona (para no bloquear la interfaz) y actualiza únicamente un trocito de la página, que es el que se ve afectado por tu acción. Imagínate que cada vez que dices “Me gusta” en Facebook se recargara por completo la página entera. se haría insufrible y dudo mucho que tuviera el éxito actual. Lo mismo se aplica a los clientes Web para correo electrónico como los mencionados. Ya nadie concibe pulsar sobre una de tus carpetas de correo (o tags en el caso de GMail) en el lateral, y que de repente se cargue de nuevo la página completa. La experiencia debe ser integrada, como la de cualquier aplicación de escritorio.

integrada, como la de cualquier aplicación de escritorio. Figura 1.- la interfaz de Facebook usa de

Figura 1.- la interfaz de Facebook usa de manera intensiva técnicas AJAX.

Desde que el hTML Dinámico (hTML + Javascript) y las hojas de estilo css hicieron su aparición, cada vez más aplicaciones hacen uso de las posibilidades de modificación “al vuelo” de contenidos que estas tecnologías brindan, consiguiendo los resultados que acabo de describir. en la actualidad todos los navegadores ofrecen soporte para DhTML por lo que si quieres escribir programas complejos de lado

Fundamentos de AJAX

11

de cliente, que interactúen con los contenidos de la página, no implica como antes tener que dejar fuera a parte de tus posibles usuarios. a la combinación de hTML dinámico con tecnologías de servidor se le denomina de manera genérica aJaX. este simpático acrónimo hasta hace poco asociado con el apasionante mundo de la limpieza y con el fútbol, viene del concepto en inglés Asynchronous JavaScript And XML. se basa en el uso de un objeto llamado XMLHttpRequest, presente en todos los navegadores modernos, que como es de imaginar por su nombre sirve para hacer peticiones al servidor de documentos XML

a través del protocolo hTTP. Utilizado este objeto se solicitan al servidor datos en

formato XML que, una vez recibidos en el navegador, es posible manipular mediante código Javascript y mostrar el resultado dentro de los elementos de la página. esta es la idea original de esta técnica, pero como comprobaremos en breve, de este punto inicial a lo que existe actualmente las cosas han cambiado mucho. aunque casi todo el mundo se piensa que esto de aJaX es un invento de Google

y su potente cliente Web de correo electrónico GMail (primera aplicación que en

verdad lo popularizó), el objeto XMLHttpRequest apareció originariamente junto a las bibliotecas XML de Microsoft (MsXML) a finales de los años noventa del siglo pasado. el concepto original de esta tecnología fue creado también por Microsoft (se llamaba Remote Scripting), el primer navegador en soportarlo fue Internet explorer

y la primera aplicación de este tipo fue outlook Web access (oWa), para acceder

a buzones exchange. como veremos enseguida, aparte de que su nombre original haya perdurado por ser simpático, la realidad es que aJaX no siempre es asíncrono ni tampoco siempre

usa XML. De hecho lo más habitual es que hoy en día utilice otro formato para transferir los datos: JsoN, que estudiaremos luego. Lo que de verdad constituye el corazón de de esta técnica es el objeto XMLHttpRequest. en este capítulo vamos a estudiar los fundamentos de la tecnología para que no dependas de biblioteca alguna a la hora de implementar estas características,

y sobre todo -seamos realistas, casi nunca usarás esto “a pelo”- para que cuando

uses una de dichas bibliotecas comprendas lo que hay debajo y puedas determinar posibles problemas. conociendo bien los conceptos subyacentes tendrás muchas más herramientas para sacarle partido a las bibliotecas construidas sobre ellos, como por ejemplo la parte cliente de asP.NeT aJaX u otras muy conocidas como jQuery, YUI, script.aculo.us, MooTools, Dojo, etc

2.- uN Poco dE TEoríA: El obJETo XMlhTTPrEQuEST

Para sacar partido a aJaX, aparte de tener conocimientos de hTML y Javascript, el primer objeto que debemos conocer a fondo es el mencionado XMLHttpRequest. se trata de una clase disponible en todos los navegadores modernos que permite lanzar desde Javascript peticiones de recursos GeT Y PosT a través de hTTP. Dicho en lenguaje simple, lo que esta clase nos permite es simular mediante código Javascript llamadas al servidor como si éstas hubieran sido hechas por los usuarios.

12

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

el efecto es el mismo que si el usuario hubiese enviado un formulario o pulsado

sobre un enlace, sólo que nuestro código es el que tiene el control sobre ello y lo gestiona de manera independiente al contenido actual de la página (en la jerga se suele decir que lo gestiona “por debajo”). aunque en el caso de Internet explorer se sigue exponiendo su funcionalidad como un objeto ActiveX en el resto de los navegadores (Firefox, safari, chrome,

opera

Los métodos y propiedades básicos de esta clase que debemos conocer son los

siguientes (los corchetes indican parámetros opcionales):

)

éste forma parte ya de sus clases nativas.

open(método, UrL, [asincrono], [usuario], [clave]): sirve para abrir una conexión al servidor. No envía ni obtiene información, sólo se conecta. el primer parámetro indica de qué manera queremos enviar la petición al servidor: por GeT o por PosT. el segundo es la dirección Web a la que vamos a llamar. el tercer parámetro es booleano y sirve para indicar si la conexión se realizará de forma asíncrona (por defecto) o no. Los dos últimos parámetros sirven para especificar un nombre de usuario y una contraseña de acceso para recursos protegidos por autenticación básica, si bien esto es bastante absurdo pues estarán escritos en claro en el Javascript, por lo que raramente se utilizan.

send(contenido): envía una petición. si es un envío por PosT se pueden incluir los datos a enviar en su único parámetro, si no se usa un nulo.

abort(): cancela un envío/petición abierto previamente.

onreadystatechange: a esta propiedad se le asigna una referencia a un mé- todo Javascript que será llamado automáticamente cuando se descargue del todo la UrL remota (cuando se llama a ésta asíncronamente).

readyState: informa del estado de la petición:

o

0=no iniciada

o

1=cargando

o

2=terminada pero sin procesar

o

4=completada.

status: código de estado hTTP resultado de la petición: por ejemplo 200

se corresponden con los códigos de estado

de hTTP (los puedes consultar aquí: http://www.w3.org/Protocols/HTTP/

(éxito), 404 (no encontrado), etc

HTRESP.html).

statusText: mensaje de información correspondiente al estado anterior.

responseXML: documento DoM que representa el XML devuelto por la petición. sólo se utiliza si lo que esperamos obtener es un documento XML.

Fundamentos de AJAX

13

en la actualidad no se utiliza casi nunca pues el XML se ha abandonado en aJaX a favor de JsoN, que luego veremos.

responseText: el contenido puramente textual del recurso remoto. es la que usaremos habitualmente para obtener el contenido del recurso solicitado.

aunque dispone de algunos métodos y propiedades más, con estas tendremos sufi- ciente para el 99% de los casos que nos vamos a encontrar.

3.- bASTA dE TEoríA: vAMoS A lA PrÁcTicA

veamos cómo se usa la clase XMLHttpRequest en la práctica con un ejemplo sencillo. consideremos algo simple como el ejemplo de la figura:

consideremos algo simple como el ejemplo de la figura: Figura 2.- Ejemplo de lista desplegable auto-completada

Figura 2.- Ejemplo de lista desplegable auto-completada con AJAX

hay una lista desplegable que contiene una serie de categorías. al elegir una de éstas, en la lista de al lado deberán aparecer los elementos que contiene rellanándolos dinámicamente con lo que nos indique una página en el servidor, pero sin recargar la página. este ejemplo es muy sencillo pero nos ayuda a centrarnos sólo en la parte que nos interesa, que es la de cliente y en cómo realizar las llamadas aJaX. Lo que debemos hacer para que esto funcione es responder a los eventos de cambio de selección de la primera lista y lanzar “por debajo” una petición a una página del servidor que nos devolverá los elementos de la lista secundaria. en un ejemplo real los elementos se obtendrían, en la página del servidor, seguramente desde una base de datos.

14

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

Lo primero que debemos hacer para lanzar una llamada al servidor desde nuestro código Javascript es obtener una referencia a un objeto de la clase XMLHttpRequest que será el que utilizaremos. Dado que Internet explorer es diferente a los demás na- vegadores en este aspecto, debemos distinguir con quién estamos trabajando para poder instanciarlo. Podemos encapsular esta funcionalidad con el código del listado 1:

listado 1

function getHttpRequest()

{

var httpReq;

//Si es Mozilla, Opera, etc if (window.XMLHttpRequest)

{

httpReq = new XMLHttpRequest();

}

else //Internet Explorer lo expone como control Active X

{

httpReq = new ActiveXObject(“Microsoft.XMLHTTP”);

}

}

así dispondremos de una función getHttpRequest que nos devolverá una instancia del objeto XMLHttpRequest independientemente del navegador. Una vez que tenemos una referencia al objeto usaremos sus métodos y propiedades para lanzar una petición a la página de servidor que nos interese, por ejemplo así:

http = getHttpRequest() http.onreadystatechange = finCarga; http.open(“GET”, “http://www.miserv.com/misdatos.aspx”, true) http.send(null);

en la segunda línea, y antes de llamar a la página del servidor, establecemos una referencia a la función que se llamará automáticamente cuando cambie el estado de la petición que vamos a lanzar. ello no implica que ésta tenga éxito o que sea llamada sólo cuando termine, como veremos enseguida. La tercera línea abre el conducto de petición al servidor para cargar una deter- minada UrL de modo asíncrono (true en el tercer parámetro). en este caso usará el método GeT pues no enviamos datos al servidor. Por fin debemos hacer la llamada (el open de la línea anterior no la hace sólo la prepara), usando para ello el método send. se le pasa un nulo porque no enviamos ninguna información extra (es una petición GeT). el hecho de que sea una llamada asíncrona hará que se devuelva el control inmediatamente a Javascript al pasar por esta línea, por lo que podríamos tener más código a continuación para llevar a cabo más tareas sin que se viera interrumpida la ejecución ni la interacción con el usuario. Podríamos usar llamadas síncronas ( false en el tercer parámetro) para lanzar varias

Fundamentos de AJAX

15

llamadas seguidas con la certeza de que se ejecutarán en un determinado orden. es decir, como vemos, aJaX en realidad no siempre debe ser asíncrono. obviaremos de momento el código de la página del servidor que podría ser cualquiera (acceder a una base de datos para obtener los elementos, leer un ar-

Lo único verdaderamente importante es ponernos de

acuerdo en cómo la página del servidor va a devolver los resultados de la petición. Podemos complicarlo todo lo que queramos usando XML o cualquier otra notación que consideremos oportuna. Más tarde retomaremos este tema. De momento para acabar con el ejemplo vamos a suponer simplemente que el servidor nos devuelve una lista, separando con comas los elementos que se desean mostrar en el control secundario. como hemos visto se define una función llamada ‘fincarga’ que es llamada de manera automática al ir cambiando el estado de la petición. veamos cómo es su aspecto en el listado 2:

chivo o la memoria, etc

).

listado 2

function finCarga()

{

 

if (http.readyState == 4) //4: completado

{

if (http.status == 200) //200: OK

{

res = http.responseXML; Procesarespuesta();

}

else //Se produjo un error

{

alert(“No se pudo recuperar la información: “ + http.statusText);

}

}

}

Lo único que hacemos aquí es detectar cuándo se ha terminado la petición (ready- State será igual a 4 como hemos visto antes) y que ésta haya sido una petición exitosa (el código de estado hTTP debe ser 200). si el código hTTP es 404 (no encontrado), 500 (error en el servidor) u otro cualquiera se advierte con un mensaje al usuario. en caso positivo lo único que hacemos es anotar la respuesta del servidor en una variable global de la página (res en el ejemplo) y procesar el resultado adecuadamente. en este caso se separan los elementos con las comas y se carga la lista secundaria. Dado que es un código Javascript trivial y no aporta nada al tema que nos ocupa no lo he incluido aquí, pero lo puedes ver en el archivo con los ejemplos del libro. Lo único que se usa normalmente al mostrar los resultados son los conocidos métodos getElementsByTagName y getElementByID de hTML dinámico y del DoM. estudia el ejemplo incluido en el ZIP para ver exactamente como se ha hecho.

16

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

este ejemplo tan sencillo constituye en realidad todo lo que es necesario saber sobre los fundamentos de funcionamiento de aJaX.

4.- ProblEMAS TíPicoS dE AJAX y SuS SolucioNES

ahora que ya conocemos los rudimentos de aJaX vamos a ver cuáles son los princi- pales problemas que nos podemos encontrar al usar estas técnicas, y que en ocasiones pueden ser complicados de detectar. Probablemente, serán los mismos que nos encon- traremos si utilizamos alguno de los paquetes específicos para aJaX como asP.NeT aJaX y las otras mencionadas, por lo que debemos ser conscientes de ellos. Los más importantes son los siguientes:

1. Llamadas fuera del dominio.

2. Llamadas que producen errores o que no vuelven jamás.

3. envío de datos al servidor.

4. contenidos no actualizados debido a cachés.

4.1.- llamadas fuera de dominio

Una vez que uno empieza a juguetear con las posibilidades de aJaX enseguida se nos ocurren ideas geniales para sacarle partido. La más obvia, claro está, es la de utilizar las técnicas para acceder desde el cliente a ciertos servicios Web ajenos de utilidad ubicados en Internet. así, dado que los servicios Web están basados en XML, es muy fácil procesar lo que devuelven con las técnicas descritas para, por ejemplo, realizar búsquedas en amazon con su aPI, seguir una subasta en eBay, enviar “posts” a nuestro blog, consumir fuentes rss, etc Todo esto es estupendo pero tiene un gravísimo problema: los navegadores, por cuestiones de seguridad, bloquean todas las peticiones realizadas mediante XmlHttpRequest a dominios que no sean el que aloja la página desde la que se está usando. en realidad se trata de una restricción bastante lógica y que aparece en otras par- tes del navegador, como las cookies, el acceso a variables de Javascript entre marcos, los objetos Flash o los applets de Java. Pero esto, claro está, supone una limitación importante para ciertos tipos de aplicaciones aJaX que podríamos desarrollar, como las de los ejemplos comentados. La pregunta ahora es entonces: ¿cómo solventamos esta situación? en Internet explorer basta con bajar el nivel de seguridad para que ya funcione correctamente, pero no es una buena solución (no le puedes pedir esto a tus usuarios). en otros navegadores (Firefox, opera, chrome y safari) no hay forma de saltarse esta restricción. existe una salvedad en Firefox que consiste en firmar digitalmente el Javascript que usas, pero tampoco vale de mucho pues sólo funcionaría en este navegador. La única forma de solucionarlo de manera independiente al navegador es, aunque sea de Perogrullo, hacer que no dependa de éste, es decir, llevarnos el problema al

Fundamentos de AJAX

17

servidor. Para ello lo que debemos hacer es construir un servicio proxy que esté en nuestro servidor (al que sí podremos llamar con aJaX) y que sea éste el que se encargue de realizar la llamada a otros dominios devolviendo el resultado a nuestro Javascript (directamente o pre-procesándolo de algún modo). en .NeT esto implica generalmente crear un manejador de peticiones con exten- sión .ashx o un servicio Web propio que se encargue de realizar por nosotros las peticiones que nos interesen. ¡Mucho ojo con esto!. Normalmente este tipo de servicios -al igual que los que se encargan de leer archivos de disco de manera genérica y otros similares- son un verdadero peligro de seguridad si no los programamos bien. si optas por esta solución lo mejor es que tomes varias precauciones de cara a la seguridad: tener muy acotados los servicios o UrLs a los que se puede llamar desde el proxy. Lo mejor es identificarlos a cada uno con un número o código decidiendo a cuál se llama (con una cláusula switch en c# o Select Case en vB.NeT), nunca poniendo la URL directamente en la llamada desde JavaScript. otra medida adicional es tratar de identificar al script llamante de alguna manera:

mediante una cabecera que te debe enviar, comprobando el dominio del “referer” y cosas similares. está claro que un cracker experimentado se puede saltar esto pero le dará bastante trabajo y elimina de un plumazo a los aficionados que quieran hacer uso ilícito de tu servicio. si puedes limita el número máximo de llamadas seguidas que se puede hacer desde una determinada IP o, mejor, en una determinada sesión de servidor. Toda precaución es poca.

4.2.- gestión de errores y llamadas que no vuelven

No podemos asumir que las llamadas que hagamos al servidor van a funcionar siem- pre. Puede haber un error en el código del servidor, es posible que haya cambiado la UrL y que no aparezca la página que llamamos, o que haya errores de permisos,

Lo que pase en el servidor está fuera de nuestro control. ante eso hay que estar

etc

preparado. La forma de controlar estas situaciones es, como en cualquier componente de comunicaciones por hTTP, a través del código de estado que devuelva el servidor. Todo esto ya se había apuntado antes y se había tenido en cuenta en el código del listado 2. Podríamos afinar más en el mensaje de error y devolver uno diferente según el código de estado. hay, sin embargo, una situación menos frecuente pero más peligrosa que se puede producir: que la llamada asíncrona al servidor no vuelva o no lo haga en un tiempo razonable, es decir que se produzca lo que se denomina un timeout. ¿Qué hacemos en ese caso? No podemos contar con la notificación de final de carga puesto que, al no regresar

la llamada no saltará, así que el listado 2 no nos sirve. Lo que se hace en estos casos es establecer un temporizador con el tiempo máximo que deseemos esperar, para que al cabo de ese intervalo la petición sea anulada directamente, sin esperar más que llegue la respuesta. Podemos verlo en el listado 3:

18

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

listado 3

http = getHttpRequest() http.onreadystatechange = finCarga; http.open(“GET”, “http://www.miserv.com/misdatos.aspx”, true) var tmrAnular = setTimeout(“AnularPeticion()”, 20000); //20 segundos http.send(null);

function AnularPeticion()

{

http.abort();

}

function finCarga()

{

if (http.readyState == 4) //4: completado

{

clearTimeOut(tmrAnular);

if (http.status == 200) //200: OK

{

res = http.responseXML;

Procesarespuesta();

}

else //Se produjo un

error

{

alert(“No se pudo recuperar la información: “ + http. statusText);

}

}

}

se ha modificado el código de llamada anterior para añadir la creación de un temporizador que se encarga de anular la petición al pasar un tiempo determinado (en este caso de 20 segundos pero puede ajustarse a cualquier otro valor). Nótese también como en el evento de fin de carga eliminamos el temporizador (que ya no nos hace falta) cuando la petición termina de procesarse, en caso de que regrese.

4.3.- Envío de datos al servidor

Normalmente cuando pensamos en aJaX, es decir, en llamadas asíncronas a servi- cios, lo hacemos desde el punto de vista de obtener información: llamo a una página que me devuelve unos valores y los muestro en la interfaz de usuario. aunque este

Fundamentos de AJAX

19

es el uso más común de aJaX lo cierto es que también es muy útil usarlo en el sentido inverso, para enviar datos al servidor. Las utilidades y necesidades que cubre son múltiples y de hecho hay muchos sistemas que le sacan partido. La forma más sencilla y directa de enviar datos simples al servidor es incluirlos en la U r L a la que llamamos como parámetros GeT:

urldestino.aspx?Parametro1=1234&Parametro2=5

aunque esto puede servirnos para cosas muy sencillas no es lo que necesitaremos en la mayor parte de los casos. Lo habitual es que la información haya que enviarla con el método PosT. La principal diferencia entre GeT y PosT estriba en que el método GeT hace una sola llamada al servidor, solicitando una página y enviando algunos parámetros de datos en la propia petición. PosT por el contrario realiza dos conexiones al servidor. en la primera solicita una UrL y en la segunda envía los datos. Por GeT lo máximo que se puede enviar son 2 kB de información, mientras que por PosT no existe esta limitación. Para enviar datos al servidor mediante PosT nuestro código aJaX sería similar al siguiente:

http = getHttpRequest() http.onreadystatechange = finCarga; http.open(“POST”, “http://www.miserv.com/misdatos.aspx”, true)

http.send(‘Parametro1=1234&Parametro2=5’);

con esto no hemos ganado demasiado. ahora se envían los datos por PosT (sólo cambia el primer parámetro de open) pero los hemos tenido que introducir en el método send en lugar de en la propia UrL. esto sólo simularía el envío de parámetros mediante PosT desde un formulario hTML, aunque por otro lado en ocasiones puede ser lo que queramos. Lo habitual sin embargo es que, en lugar de enviar parámetros, queramos enviar información pura y dura del tamaño que sea preciso, que es para lo que suele usarse PosT. esto se puede conseguir modificando ligeramente el código anterior para incluir una cabecera que indique al servidor que lo que le llega son, precisamente, datos (línea 3 del siguiente fragmento):

http = getHttpRequest() http.onreadystatechange = finCarga; http.setRequestHeader(‘content-type’, ‘application/x-www-form- urlencoded’); http.open(“POST”, “http://www.miserv.com/misdatos.aspx”, true) http.send(‘Aquí ahora mando la información que quiera al servidor’);

con esto nuestro problema queda resuelto.

20

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

4.4.- contenidos no actualizados debido a cachés

cuando se envía una petición hTTP es posible que, si la caché del lado servidor no está correctamente configurada, el navegador realice su propia caché local. Por lo tanto

la próxima vez que realicemos una llamada a la misma UrL, el navegador en lugar de hacerla sacará el mismo resultado anterior de esa caché local, y por lo tanto la llamada no llega al servidor jamás. o puede que exista un proxy-caché por el medio (Teléfonica por ejemplo las ha utilizado tradicionalmente en sus servicios de acceso a Internet) que almacena peticiones anteriores y por lo tanto obtenemos únicamente una copia, sin realizar la llamada al servidor real. eso muchas veces es lo que querremos para ahorrar procesamiento y será maravilloso, pero lo habitual es que sea una maldición ya que evitará que obtengamos datos actualizados.

a la hora de enviar datos por PosT no hay problema porque no actúa nunca

la caché. el problema, si se da, está en las peticiones GeT, por otro lado las más habituales.

si el servidor tiene bien configurada la caché (es decir, indica cuándo caducan

los contenidos o marcamos en IIs que éstos caduquen inmediatamente) no debe- ríamos experimentar fallos, salvando lo comentado respecto a los proxy-caché de

algunos proveedores.

si queremos asegurarnos de que la petición va a llegar a su destino podemos

hacer fundamentalmente dos cosas:

1. agregar una cabecera que indique que se debe obtener el contenido siempre que éste sea posterior a una fecha, por ejemplo así:

http.setRequestHeader(‘If-Modified-Since’, ‘Wed, 1 Jan 1972 00:00:00 GMT’);

Indicaremos siempre una fecha anterior a la actual como la del ejemplo y así siempre se pedirá la última versión al servidor.

2. añadir un número aleatorio (o cadena) a la UrL de cada petición. en este caso suele funcionar muy bien el agregarle una marca temporal, es decir, añadir a continuación la fecha y hora actuales, de modo que cada una de las peticiones que se hagan va a ser diferente y por lo tanto los caché que existan por el medio tienen que repetir siempre la petición. Por ejemplo:

http.open(“POST”, “http://www.miserv.com/misdatos.aspx?pasacache=” + new Date().getTime(), true);

se le añade un parámetro que lleva como valor la fecha y hora en formato numérico (es decir, un número muy largo y que varía varias veces cada milisegundo), por lo que es muy difícil que se den dos peticiones idénticas incluso a través de un proxy-caché. además ese parámetro extra de nombre inventado que nosotros le añadimos no debería afectar en absoluto a la llamada puesto que no está siendo

Fundamentos de AJAX

21

tenido en cuenta por la aplicación. esta segunda técnica es la más fiable, aunque un poco más tediosa de implementar.

5.- dEvolucióN dE iNForMAcióN: JSoN

en el ejemplo anterior hemos hecho que la página del servidor devuelva ciertos valores que en este caso tenían formato XML, pero que podrían tener perfectamente otra configuración distinta, como por ejemplo simples valores separados por comas. si bien esto puede ser suficiente en los casos más sencillos, en otras ocasiones necesitaremos manejar estructuras de datos más complejas. Dado que hTTP es un protocolo basado en texto, el recurso al que llamemos en el servidor debe devolver siempre texto (o sea, no puede ser una imagen o un archivo binario, que para transferirse se codifican de una forma especial -Base64- para convertirlos en texto). este texto devuelto puede tener cualquier formato: texto plano, XML, código Javascript o incluso hTML. en este último caso podemos obtener desde el servidor un contenido hTML completo que se debe escribir en una zona de la página (por ejemplo dentro de un <DIv> o un <sPaN>). sin embargo la mayor parte de las veces lo que tendremos que procesar es alguna estructura de datos. Ya hemos mencionado que la ‘X’ de a Ja X significa XML, pues era el formato de moda a finales de los 90 y principios de los 2000 y se usaba para todo. como se demostró en nuestro sencillo ejemplo este formato no es necesariamente el que se va a devolver. De hecho hoy en día el XML se usa muy poco a la hora de representar los datos textuales devueltos desde el servidor en páginas aJaX. el motivo de esto es principalmente que los datos representados con XML, si bien son ricos en estructura, hacen que el resultado devuelto ocupe mucho debido a las etiquetas de apertura y cierre de los diferentes nodos. Gracias al DoM es fácil procesar la información jerárquica que se representa mediante XML, aún así debería existir algún método más directo, más rápido y que ocupe menos ancho de banda. como alternativa a XML surgió un nuevo formato programable llamado JsoN (pronunciado “yeison”) que lo reemplaza con mucha ventaja en la mayor parte de los casos. JsoN es el acrónimo de JavaScript Object Notation, y como su propio nombre indica permite representar objetos (en realidad estructuras complejas) en forma de código Javascript que luego podemos evaluar. JsoN tiene varias ventajas sobre XML, a saber:

1. ocupa mucho menos al transmitirlo por la red.

2. el acceso en el navegador a los elementos de datos representados es directo y sin necesidad de procesamiento farragoso usando el DoM o expresiones regu- lares, ya que se trata directamente de Javascript que se puede interpretar.

3. Los datos pueden ir colocados en cualquier posición.

consideremos el siguiente código XML que representa los datos de un cliente:

22

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

<cliente> <nombre>José Manuel</nombre> <apellidos>Alarcón Aguín</apellidos> <empresa>Krasis</empresa> <telefono>902 876 475</telefono>

<edad>37</edad>

</persona>

ahora consideremos la misma representación en JsoN:

{

“nombre” : “José Manuel”, “apellidos” : “Alarcón Aguín”, “empresa” : “Krasis”, “telefono” : “902 876 475”, “edad” : 37

}

crearlo es muy fácil pues es sintaxis Javascript normal. en www.json.org es posible encontrar una explicación completa de esta notación. La Wikipedia también tiene una información muy completa sobre ello. como se puede comprobar ocupa menos que el XML equivalente, es igual o incluso más fácil de leer que éste, y permite usar datos nativos y no sólo cadenas para representar los valores. en estructuras de datos más complejas se puede apreciar más todavía el ahorro de datos que implica. De todos modos lo más espectacular de JsoN es lo fácil que resulta usarlo. Basta con escribir lo siguiente:

var cliente = eval(res);

siendo ‘res’ el nombre de la variable que contiene el JsoN obtenido del servidor. es decir, lo único que hacemos es procesar la expresión JsoN. al hacerlo obtenemos en la variable ‘cliente’ un objeto cuyas propiedades son los datos que queremos manejar. De este modo lo único que tenemos que hacer para leerlos es escribir directamente expresiones como esta:

alert(“El nombre de la empresa es “ + cliente.empresa);

Más fácil imposible. Nada de recorrer una jerarquía XML con el DoM o ir buscando nodo a nodo en el contenido. se convierte en Javascript puro y utilizable nada más llegar desde el servidor. el uso de JsoN como formato de intercambio sólo tiene dos problemas aparentes. el primero de ellos es el más obvio: generar XML con c# o vB.NeT es muy fácil pero generar JsoN ha requerido tradicionalmente un cierto trabajo por nuestra parte. Para evitárnoslo las últimas versiones de .NeT (3.5 o superior) incluyen la posibilidad

Fundamentos de AJAX

23

de que los servicios Web y WcF (Windows Communication Foundation) generen sus resultados directamente en JsoN. existen además bibliotecas especializadas en generar JsoN si estamos interesados en hacerlo de manera manual. Por ejemplo, una muy famosa es Jayrock (http://jayrock.berlios.de) que permite convertir objetos .NeT directamente a su representación JsoN. el otro problema es tal vez menos evidente pero más importante: la seguridad. Dado que se usa una expresión ‘eval’ para convertir el texto en objetos Javascript podría utilizarse de manera malintencionada para inyectar código peligroso en la página al efectuar la evaluación. Para evitarnos este peligro con código en el que no confiamos, en JsoN.org tenemos un script (http://www.json.org/json.js) que extiende las cadenas de Javascript para convertirlas a JsoN verificando la sintaxis y evitando todo aquello que no sean datos. si incluimos este script en nuestra página en lugar de utilizar ‘eval’ podemos escribir:

var cliente = res.parseJSON();

para obtener el mismo resultado. además nos ofrece la funcionalidad inversa de la siguiente manera:

var miCadena = cliente.toJSONString();

esto nos puede servir para enviar datos JsoN al servidor, para almacenar un objeto en una cookie, etc

6.- EN rESuMEN

en este capítulo hemos aprendido los fundamentos de aJaX así como los principales problemas que nos podemos encontrar al utilizarlo. La comprensión de todo ello nos va a resultar útil aunque no usemos estas técnicas de “bajo nivel” sino que recurramos a un kit especializado como asP.NeT aJaX, o cualquiera de las múltiples bibliotecas de Javascript con soporte aJaX existentes en el mercado. Lo habitual será que siempre implementemos características aJaX en nuestras páginas usando alguna biblioteca especializada. en el mundo Microsoft emplearás con toda seguridad la parte cliente de asP.NeT aJaX, así como la biblioteca de código abierto JQuery, que se soporta oficialmente a partir de visual studio 2010. en el próximo capítulo vamos a estudiar las principales características de asP.NeT aJaX en el lado de servidor, que se traducen en mejoras en el lado del cliente.

cAPíTulo 3
cAPíTulo
3

A s P. net AJAX en el servidor

como hemos visto en el capítulo anterior, aJaX es un gran aliado a la hora de mejorar la usabilidad y la capacidad de respuesta de la interfaz de nuestra aplicación Web. Las técnicas aJaX nos evitan tener que refrescar la página completa cada vez que se genere un evento de servidor, lanzando las peticiones en segundo plano y refrescando sólo las partes de la interfaz que sean apropiadas en cada caso. conseguir todo esto directamente con nuestro propio código Javascript en el navegador puede convertirse en una tarea tediosa, que necesita bastante trabajo y es propensa a errores. Para evitarnos estos problemas y facilitarnos la tarea asP.NeT incluye una biblioteca especializada en creación de aplicaciones aJaX. Microsoft, en un alarde originalidad, llamó a esta biblioteca asP.NeT aJaX. su nombre anterior, cuando estaba todavía en versión Beta, era “atlas” y la verdad es que a casi todo el mundo le gustaba más :-)

Nota:

como ya comenté en el capítulo de introducción, asP.NeT aJaX está incluido en.NeT de ma- nera nativa a partir de su versión 3.5 (y versión 2008 de visual studio) y en todas las versiones posteriores. en asP.NeT 2.0 la biblioteca se debe descargar e instalar por separado para poder utilizarla. Puedes encontrarla en www.asp.net/ajax. No hay soporte para aJaX en las versio- nes 1.0 y 1.1 de asP.NeT, ya completamente desfasadas.

La biblioteca de aJaX se divide en dos partes claramente diferenciadas pero que trabajan de manera conjunta para dotarnos de funcionalidad:

· Biblioteca de servidor: contiene un conjunto de controles Web que abstraen de manera muy efectiva las tareas que deberíamos hacer normalmente en el cliente. Generan todo el código necesario para gestionar de manera asíncrona las llamadas al servidor y las actualizaciones. Los dos más importantes son el control ScriptMa- nager y el UpdatePanel. en la figura se pueden observar los controles dentro del cuadro de herramientas de visual studio.

26

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

tecnologías A s P. net 4.0 (saltando desde la versión 2.0) Figura 1.- controles de servidor

Figura 1.- controles de servidor para AJAX

· Biblioteca de lado cliente: se trata de una serie de scripts en Javascript que extienden las capacidades de este lenguaje para facilitar la creación de código en el navegador (código de lado cliente). La parte servidora se basa en estas funciones para generar su funcionalidad. ofrece, por ejemplo, capacidades avanzadas de orien- tación a objetos para Javascript, creación de controles reutilizables, capacidad para crear scripts localizados, llamadas a servicios Web desde el cliente y, por supuesto, características para el control de las comunicaciones con el servidor. La funcionalidad de lado cliente es, en verdad, la parte más compleja de asP. NeT aJaX y le dedicaremos dos capítulos del libro. en este nos vamos a centrar en la funcionalidad generada desde el servidor.

1.- uN PriMEr EJEMPlo: MEJorA dE uNA APlicAcióN bÁSicA coN AJAX

Para empezar a abrir boca con asP.NeT aJaX vamos a reproducir el ejemplo sencillo del capítulo anterior de fundamentos usando asP.NeT. veremos cómo se comporta al tratarse de una aplicación asP.NeT normal y luego lo fácil que es convertirlo en una aplicación aJaX. Nos servirá para conocer los fundamentos de la parte servidora de la aPI de aJaX. crea un nuevo sitio Web con visual studio y en la página por defecto añade dos controles DropDownList, uno a continuación del otro separados con un par de espacios en blanco. en el primero de ellos habilita el “auto postback” de modo que se genere automáticamente un evento SelectedIndexChanged en el servidor cada vez que se seleccione un elemento diferente de la lista. Usa la opción de editar elementos en su menú de tareas para añadir cuatro categorías: revistas, Blogs, empresas y Libros.

añadir cuatro categorías: revistas, Blogs, empresas y Libros. Figura 2.- El menú de tareas del control

Figura 2.- El menú de tareas del control dropdownlist

A s P. net AJAX en el servidor

27

ahora vamos a responder a su evento de selección para introducir en la segunda lista los elementos correspondientes a la categoría seleccionada. haz doble clic en el control DropDownList1 para obtener la definición del manejador de eventos para su evento SelectionIndexChanged y escribe el siguiente código:

Protected Sub DropDownList1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList1. SelectedIndexChanged Select Case DropDownList1.SelectedValue.ToLower() Case “revistas”

DropDownList2.Items.Clear()

DropDownList2.Items.Add(New ListItem(“dotNetMania”)) DropDownList2.Items.Add(New ListItem(“MSDN

Magazine”))

DropDownList2.Items.Add(New ListItem(“CodeProject”)) Case “blogs”

DropDownList2.Items.Clear()

DropDownList2.Items.Add(New ListItem(“www.jasoft.

org”))

DropDownList2.Items.Add(New ListItem(“www.geeks.ms”)) DropDownList2.Items.Add(New ListItem(“weblogs.asp.

net”))

Case “empresas”

DropDownList2.Items.Clear()

DropDownList2.Items.Add(New ListItem(“Krasis [www.

krasis.com]”))

DropDownList2.Items.Add(New ListItem(“Microsoft [www. microsoft.com]”)) DropDownList2.Items.Add(New ListItem(“Plain Concepts [www.plainconcepts.com]”)) Case “libros”

DropDownList2.Items.Clear()

DropDownList2.Items.Add(New ListItem(“Crimen y

castigo”))

DropDownList2.Items.Add(New ListItem(“Cien años de

soledad”))

DropDownList2.Items.Add(New ListItem(“El Quijote”)) End Select End Sub

con esto tenemos suficiente para demostrar la diferencia entre una aplicación Web corriente y una con soporte para aJaX. ejecuta la aplicación pulsando F5 (acepta el diálogo que te avisa que se va a modificar web.config para dar soporte a la depuración) y cuando se abra el navegador juega un poco con la interfaz cambiando la selección en la primera lista.

28

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

como puedes comprobar, cada vez que eliges un elemento nuevo en la lista 1, se produce un postback al servidor y al regresar la página, ésta se recarga y muestra los elementos apropiados en la segunda lista. Los efectos molestos de esta aplicación tan sencilla son fáciles de ver:

1. Durante la recarga de la página se produce un claro parpadeo, correspon- diente al borrado de la página original y la subsiguiente recarga de ésta con los nuevos valores. si usas Internet explorer además oirás un sonidito (como un “clac”) en cada recarga.

2. La primera vez que haces una selección normalmente la página tarda un poco más de lo habitual en ejecutarse. Durante quizá medio segundo el usuario no tiene ni idea de si la acción que ha llevado a cabo en la interfaz (en este caso seleccionar una categoría de la lista) ha tenido efecto o no. en algunas aplicaciones reales en las que el código es más complicado y puede que haya demoras de e/s debido a accesos a bases de datos, a disco o a redes con- gestionadas, las esperas para recibir las respuestas a eventos de servidor pueden tardar incluso varios segundos, durante los cuales el usuario no tiene ni idea de qué está pasando.

3. Un efecto muy desagradable de los postback y del que muchos programadores no se percatan es el de las entradas indeseadas en el historial de navegación. en nuestro ejemplo cada vez que seleccionamos un elemento de la lista y se provoca un postback aparece una nueva entrada en la historia del navegador. si el usuario pulsa la flecha para ir a la página anterior irá pasando por cada una de las selecciones que haya hecho en la lista. sin embargo el usuario ha tenido la sensación de estar trabajando todo el tiempo en la misma página. Para él o ella debería ser transparente el hecho de que nosotros por debajo estemos reenviando la página. cuando pulsa el botón de volver a la página anterior lo que un usuario espera es realmente volver a la “pantalla” en la que estuviese previamente, no a los sucesivos pasos de trabajo en la misma página actual. Por supuesto existen excepciones y a veces será necesario todo lo contrario: que incluso en aplicaciones aJaX se creen algunas entradas en el historial. Lo trataremos en otro capítulo con detalle.

vamos a retocar nuestro ejemplo sacándole partido a los controles aJaX que se pueden ver en la primera figura. De momento no explicaremos sus funciones y nos limitaremos a añadirlos sin más. en los siguientes epígrafes analizaremos con detalle cada uno de ellos. abre la superficie de diseño de la página asPX y desde el panel de herramientas añade un control ScriptManager que encontrarás en el grupo de extensiones aJaX. asegúrate de que el control se encuentra como primer elemento de la página, es decir, arrástralo delante del primer control DropDownList que teníamos anteriormente. ahora arrastra, justo a continuación del anterior, un control UpdatePanel. al hacerlo verás que aparece una nueva área vacía de poca altura, que es la única pista visual de que se ha arrastrado este último control.

A s P. net AJAX en el servidor

29

selecciona cada uno de las dos listas desplegables y arrástralas dentro del Up- datePanel. asegúrate de que quedan ubicadas dentro de éste. como se observa en la figura, el recuadrado sutil del control UpdatePanel nos permite ver sus límites y saber si los controles se encuentran realmente dentro de él.

si los controles se encuentran realmente dentro de él. Figura 3.- Nuestra aplicación preparada para AJAX

Figura 3.- Nuestra aplicación preparada para AJAX con sólo arrastrar dos controles.

Podríamos haber incluido los controles dentro del UpdatePanel también desde el código fuente de la página, en lugar de arrastrándolos, si cambiamos a la vista hTML y nos aseguramos de que sus etiquetas están encerradas dentro de las eti- quetas de tipo <contentTemplate> del panel, como se ve en la figura 4.

del panel, como se ve en la figura 4. Figura 4.- las etiquetas de los controles

Figura 4.- las etiquetas de los controles en el código fuente se encuentran dentro del updatePanel.

Ya está. No es necesario hacer nada más que arrastrar este par de controles. ejecuta de nuevo la aplicación. ahora verás que al seleccionar una categoría en la primera lista la segunda se recarga enseguida con los valores apropiados sin recargar la página. el parpadeo ha desaparecido y en la historia del navegador no aparecen nuevas entradas. Más sencillo imposible.

30

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

Nota:

La mayor parte de la gente se queda con esta idea de sencillez que el control UpdatePanel nos brinda. Si bien es cierto que gracias a él la creación de aplicaciones AJAX se simplifica en gran medida, también es verdad que hay multitud de pequeños detalles a tener en cuenta sobre rendimiento y optimización que se le escapan al que simplemente se queda en la superficie. ello provoca que, luego en producción y sometidas a mucha carga, algunas aplicaciones aJaX ofrezcan muchos problemas de rendimiento, ya que están hechas sin tener un buen conocimien- to de lo que se hacía. en este capítulo trataremos de comentar conceptos e ideas clave que nos ayudarán a comprender mejor toda esta tecnología. Por lo de pronto, si ya has leído el capítulo anterior de fundamentos, ya tienes más herramientas que la mayoría de los programadores asP.NeT aJaX que encontrarás por ahí.

2.- PoSTbAckS PArciAlES y rEPiNTAdoS PArciAlES dE PÁgiNA

el proceso que se lleva a cabo por debajo en las páginas aJaX como la del ejemplo anterior se denomina postback con repintado parcial de página. el funcionamiento de una página asP.NeT aJaX no difiere demasiado del de una página asP.NeT normal y corriente. ello es una gran ventaja puesto que no nos obliga a aprender conceptos diferentes o a tratar a las páginas de un modo distinto por el hecho de usar esta tecnología. Lo que ocurre durante un repintado parcial de página (en el que sólo una parte de su interfaz se modifica) es en realidad un postback completo de la misma. La diferencia con una página normal estriba en que

éste se realiza de manera asíncrona y “por debajo” usando Javascript para solicitar

la página y procesar sus resultados. La otra diferencia es que en lugar del contenido

completo se devuelve sólo el hTML que compete a los contenidos del UpdatePa- nel que se va a actualizar. el código Javascript generado automáticamente por el ScriptManager se encarga de gestionar ese resultado y repintar dinámicamente sólo la parte apropiada de la interfaz, así como actualizar los datos de estado de los controles para subsiguientes recargas de la página. en el servidor todo esto significa que cuando se produce un evento en un control, aunque se vea afectada sólo una pequeña parte de la página aJaX, en realidad se está procesando un postback completo, con todos sus eventos de ciclo de vida. es

más, se regenera totalmente el árbol de controles de la página, se lanzan todos los

eventos de ciclo de vida de éstos, se envía y recibe todo el viewstate, etc

diferencia es que se devuelve sólo el hTML de las partes de la página que se están

modificando dentro del UpdatePanel.

La única

olvidar esto es un error muy común que cometen los programadores, que no se dan cuenta de que, aunque se vaya a actualizar sólo un pequeño control, en realidad se está enviando el estado de todos los contenidos en la página (y hay ViewStates que ocupan mucho), se ejecutarán todos los eventos de página tales como Page_Load

y los eventos de ciclo de vida de todos los controles aunque no intervengan en la acción. o sea, exactamente igual que en una página normal.

A s P. net AJAX en el servidor

31

esto tiene mucha importancia ya que podemos tener una página enorme que se construye a partir de un proceso complejo y costoso (por ejemplo obtener mucha información de una base de datos o un servicio Web remoto), en la que hemos añadido un UpdatePanel en el que se modificará solamente una pequeña cantidad de información como respuesta a una acción. Podemos pensar que el refresco de ese panel será una operación ágil y muy poco costosa ya que los datos recibidos son minúsculos. es muy fácil que nos equivoquemos y la actualización parcial aparen- temente inocente lleve mucho tiempo y sea muy costosa en términos de red y de proceso en el servidor si no hemos sido cuidadosos en nuestro código. el nombre que se le suele otorgar a los postback de páginas aJaX tampoco ayuda demasiado a aclarar este concepto, ya que normalmente se les denomina en artículos y documentaciones como “postback parciales”, para distinguirlos de los “postback normales” que se ejecutan cuando no hay funcionalidad aJaX. en mi opinión deberían llamarse “postback asíncronos” o, directamente, no distinguir entre unos y otros y sólo hablar de actualizaciones parciales, que es lo que realmente ocurre. No te dejes engañar por el nombre cuando leas esta denominación y recuerda que los postback son siempre completos. La primera consecuencia de esto es que, aunque parezca que no lo necesitamos, debemos seguir comprobando en la carga de la página si nos encontramos en un postback o no, para lo cual usaremos la propiedad IsPostBack de la página. así evi- taremos operaciones de inicialización innecesarias en cada recarga, como haríamos en cualquier página normal. si por el motivo que sea necesitamos saber si nos encontramos dentro de un postback conducente a una actualización parcial de la página, o sea de un postback asíncrono de aJaX, podemos saberlo consultando la propiedad IsAsyncPostback del control ScriptManager, que tomará el valor True cuando este sea el caso.

3.- El coNTrol ScriPTMANAgEr

el núcleo sobre el que se sustenta toda la funcionalidad aJaX de asP.NeT es el con- trol ScriptManager. como sabemos, la funcionalidad aJaX de cualquier aplicación Web (sea con .NeT o no) se basa en la interacción entre el navegador y el servidor, la cual se gestiona a través de código Javascript que realiza llamadas a recursos remotos y maneja las respuestas obtenidas para actualizar la interfaz de usuario. el control scriptManager se encarga de generar todo el código Javascript necesa- rio para sustentar la funcionalidad aJaX en el navegador. como veremos al analizar la parte cliente de aJaX, este código Javascript se ofrece en forma de librerías es- pecializadas que habilitan todas las características especiales de aJaX mencionadas al principio del capítulo: llamadas a servicios Web, funciones de comunicaciones y por supuesto, como funcionalidad estrella, la capacidad de efectuar postbacks en segundo plano y hacer el repintado parcial de las páginas, que es lo que acabamos de experimentar en el ejemplo.

32

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

siempre que deseemos utilizar funcionalidad aJaX debe existir un control Script- Manager en la misma. También se pueden utilizar dentro de controles de usuario y en Master Pages, aunque luego veremos las particularidades de usarlos ahí. entre las funciones de este control están:

Generar los scripts necesarios para sustentar la funcionalidad aJaX y las extensiones de Javascript para desarrollo en el lado cliente.

registrar nuestros propios scripts en el cliente y el envío de estos dinámica- mente durante los repintados de página.

Proporcionar acceso a servicios Web en el servidor.

soporte para localización y globalización de código de lado cliente en fun- ción de los ajustes culturales del navegador.

Dar soporte a los servicios de Membership, Roles y Profile de asP.NeT para hacer uso de estos directamente desde el lado cliente, con Javascript.

Permitir la creación de controles y comportamientos basados en Javascript (extensiones) que otorgan de funcionalidad extra a los controles hTML nor- males del navegador y a los controles Web de asP.NeT.

Dado que, como vemos, este control tiene muchas funcionalidades aparte de la de permitir el repintado parcial de página, si no queremos utilizar esta característica

y sólo estamos interesados en hacer otras cosas con él en el lado cliente, podemos

desactivarla estableciendo a False su propiedad EnablePartialRendering. Por otro lado es posible que en navegadores muy antiguos la funcionalidad de repintado parcial no esté soportada. en esos casos el control ScriptManager se de- grada elegantemente y deja que la página se comporte de la manera habitual, con postbacks síncronos y repintado completo de la página. Podemos determinar esta situación consultando su propiedad SupportsPartialRendering.

4.- El coNTrol uPdATEPANEl

este control es una abstracción que nos permite indicar qué partes de nuestra interfaz de usuario queremos que tengan la capacidad de actualizarse parcialmente, de forma independiente al resto de la página. como hemos visto ya (figura 4) el marcado del control tiene una pareja de eti- quetas <ContentTemplate> que definen una zona contenedora de otros controles. Todos los controles definidos dentro de esta zona pueden participar de un repintado parcial de la página. esta región comprendida entre ambas etiquetas se corresponde en el diseñador visual de visual studio con el área contenedora del UpdatePanel a

la que podemos arrastrar los controles.

además de añadir controles en esta zona visualmente o incluyendo sus etiquetas en el marcado de la página, es posible añadirlos (o retirarlos) también dinámicamente

A s P. net AJAX en el servidor

33

mediante código. De esta forma se pueden variar en tiempo de ejecución los conteni- dos de la zona de repintado parcial. Para ello se debe manipular la colección Controls de la propiedad ContentTemplateContainer del UpdatePanel, así por ejemplo:

Dim Contenedor As Control = UpdatePanel1. ContentTemplateContainer Dim lbl As New Label() lbl.Text = DateTime.Now.ToString(“hh:mm:ss”) Contenedor.Controls.Add(lbl)

5.- ModoS dE AcTuAliZAcióN PArciAl

en una página podemos tener tantos UpdatePanel como necesitemos, para actua- lizarlos parcialmente de forma individual, coordinada o todos a la vez. Un control UpdatePanel puede contener a su vez a otros UpdatePanel, generándose una jerar- quía de actualizaciones parciales que sigue determinadas reglas. Lo más importante a tener en cuenta durante un repintado parcial es qué lo pro- voca y qué efectos tendrá sobre los diferentes UpdatePanel que tenemos repartidos por la página. cuando un UpdatePanel se encuentra dentro de otro, el del interior se actualiza siempre que lo hace su contenedor. cuando el UpdatePanel es independiente (la situación más habitual) su comportamiento durante el repintado parcial de la página viene determinado por el valor de su propiedad UpdateMode, que puede tomar los siguientes valores:

Always: si la propiedad UpdateMode tiene este valor el contenido se refresca- rá después de cualquier postback que se realice a la página, sea éste generado específicamente para este control o no. esto es importante ya que este es el valor por defecto de la propiedad. si no somos cuidadosos y tenemos varios UpdatePanel en la página veremos que, en muchas ocasiones, se actualizan zonas que no contábamos que se iban a refrescar, ya que estábamos actuando realmente en otro lugar.

Conditional: el contenido del panel sólo se repintará si el control que lanza el postback es uno de los disparadores para el UpdatePanel (ahora veremos qué es esto) o bien cuando llamamos explícitamente al método Update del panel desde un evento de servidor. Por supuesto, como ya se ha comentado, se repintará también siempre que esté contenido dentro de otro panel que se ha repintado.

Jugando con esta propiedad podemos obtener un gran control sobre en qué momento y ante qué eventos se refrescará el contenido de una zona concreta de la página.

34

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

6.- diSPArAdorES

De manera predeterminada los controles que están dentro de los UpdatePanel provocarán un repintado parcial de la página, mientras que los controles que se encuentran fuera de éstos provocarán postbacks normales con la recarga completa de la misma. aunque este comportamiento pueda resultar adecuado para muchos casos, normalmente vamos a necesitar un mayor control sobre las situaciones que provocan la recarga de las páginas y qué zonas de ésta se ven afectadas. Por ejemplo, si tenemos un control que queremos que provoque el refresco parcial de una parte de la página alejada físicamente de donde está éste ubicado, tenemos dos opciones:

1. Incluir el control y la zona que queremos actualizar dentro del mismo Up- datePanel. esto probablemente nos obligue a incluir muchos otros controles en el panel, que no nos interesa en absoluto que participen en un repintado parcial, puesto que no van a cambiar o queremos que se vean afectados por otros eventos diferentes. Llevado al extremo algunos programadores con poco conocimiento, lo que hacen es ¡rodear con un UpdatePanel todos los controles de su página!. esto es obviamente una solución muy ineficiente y como se suele decir coloquialmente es “matar moscas a cañonazos”.

2. Definir qué controles actuarán como disparadores de cada panel, y por lo tanto lanzarán postbacks asíncronos conducentes a refrescar el contenido del mismo. estos controles no tienen porqué estar dentro de un UpdatePa- nel, sino en cualquier lugar de la página. esta es la solución inteligente y optimizada.

Para implementar esta funcionalidad se definen los disparadores o Triggers. Por defecto todos los controles contenidos dentro de un UpdatePanel se compor- tan como disparadores de éste. es por ello que en el ejemplo anterior no hemos tenido que hacer nada para que funcionara el repintado parcial de la segunda lista desple- gable. este comportamiento se controla a través de la propiedad ChildrenAsTriggers del control UpdatePanel. si la establecemos como False entonces los controles que contiene no serán disparadores y tendremos que definirlos a mano. el uso más común de los disparadores es el de asociar eventos de servidor de controles externos a un panel para provocar repintados parciales de éste. visual studio nos brinda un diálogo especial que facilita su definición. vamos a verlo en funcionamiento con un ejemplo. añade al proyecto de prueba una nueva página “Triggers.aspx”. arrastra sobre ella un ScriptManager y un UpdatePanel. Dentro de este último coloca una etiqueta. ahora, fuera del panel, justo debajo, inserta un botón. el aspecto final debería ser como el de la figura 5:

A s P. net AJAX en el servidor

35

A s P. net AJAX en el servidor 35 Figura 5.- Aspecto de nuestra aplicación de

Figura 5.- Aspecto de nuestra aplicación de prueba

en el manejador del evento de pulsación del botón simplemente vamos a mostrar la hora actual dentro de la etiqueta:

Label1.Text = DateTime.Now.ToString(“HH:MM:ss”)

ahora ejecuta la página. al pulsar sobre el botón cabría esperar que la etiqueta mostrase la hora sin necesidad de recargar la página. sin embargo comprobarás que en lugar de eso se provoca un postback y un refresco de toda la página. el motivo es que el botón, al estar fuera del UpdatePanel no es automáticamente un disparador para su repintado parcial. vamos a ponerle remedio. selecciona el control UpdatePanel y en sus propiedades (pulsa F4) verás que existe una colección Triggers.

en sus propiedades (pulsa F4) verás que existe una colección Triggers . Figura 6.- colección de

Figura 6.- colección de disparadores del panel

36

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

Utilizando el botón con tres puntos situado a la derecha se abre el diálogo de gestión de disparadores, que podemos ver en la figura 7.

de gestión de disparadores, que podemos ver en la figura 7. Figura 7.- Editor de disparadores

Figura 7.- Editor de disparadores de un panel

el botón de añadir nos permite asignar uno o varios controles como disparadores del panel, es decir, como controles que van a provocar un repintado parcial del mismo. La rejilla de propiedades de la derecha nos facilita la selección de controles y eventos. en nuestro ejemplo seleccionaremos como control disparador el botón de actualizar la hora (cmdHora), y dentro de los posibles eventos de éste, el evento Click, es decir su pulsación. se podría hacer que el disparador fuese cualquier otro evento, e incluso que varios eventos de un mismo control sirvan como disparadores del panel. Una vez añadido nuestro botón como disparador, acepta para cerrar el diálogo y vuelve a ejecutar la aplicación. comprobarás como, ahora sí, al pulsar el botón la hora se visualiza en la etiqueta sin necesidad de refrescar la página por completo. si nos fijamos en el código de marcado de la página, veremos que es posible definir los disparadores del panel manualmente de forma sencilla, usando la etiqueta <Triggers>:

A s P. net AJAX en el servidor

37

</ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID=”cmdHora” EventName=”Click” /> </Triggers> </asp:UpdatePanel>

Fíjate en que lo único que necesitamos es establecer las dos propiedades del disparador como unos simples atributos de texto, indicando el nombre del control y el del evento a asociar. Los disparadores asíncronos como este se pueden utilizar también para lanzar actualizaciones parciales a partir de controles de dentro del panel cuando Children- AsTriggers es falso. También para forzar la actualización de un panel padre desde un control ubicado en un panel anidado dentro de él. Por defecto los controles que están dentro de los UpdatePanel harán un refresco parcial asíncrono de la página. en ocasiones sin embargo es posible que necesitemos que, si bien la mayoría de los controles del panel se comporten así, uno o varios de ellos provoquen un refresco completo de la página. Por ejemplo cuando un cambio dentro del panel afecta a datos que se están visualizando fuera del mismo. Para ello existen un tipo especial de disparadores que se llaman simplemente PostBackTriggers. si te fijas bien en la figura y en el listado anteriores verás que el disparador que hemos utilizado es de tipo AsyncPostBackTrigger porque desen- cadena un postback asíncrono. en la figura 7 se ve como al desplegar el botón de añadir disparador hay un tipo adicional sin el prefijo Async, siendo simplemente PostbackTrigger. este tipo de disparadores te dejan seleccionar un control contenido en el Update- Panel, y al asociarlo conseguiremos generar un postback con recarga completa de la página aunque la propiedad ChildrenAsTriggers tenga el valor por defecto de True.

7.- iNdicAcióN dE ProgrESo dE lAS llAMAdAS ASíNcroNAS

en los ejemplos que hemos hecho, las tareas realizadas como respuesta a los eventos de servidor eran triviales para poder centrarnos en la funcionalidad aJaX única- mente. en una aplicación real tendremos tareas de todo tipo que pueden ser más o

menos costosas. Por ejemplo ciertas labores de acceso a datos pueden tardar bastante en realizarse, y si le sumamos la velocidad de la red que puede ser baja, una carga

importante de usuarios en el servidor, etc

algunas de las llamadas asíncronas que se realizan al servidor tarden más de la cuenta en regresar. Mientras el navegador espera la respuesta de una llamada asíncrona para repin- tado parcial, el usuario no tiene pista alguna de lo que está pasando. en cuanto pase medio segundo y no haya un efecto visible en la página la mayoría de los usuarios

es posible —y hasta frecuente— que

38

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

se empezarán a preguntar si ha fallado algo. Incluso muchos se pondrán a pulsar los botones nuevamente varias veces para comprobar si responde, agravando el problema pues estarán lanzando más peticiones al servidor. Por eso, salvo en los casos más triviales, es importante utilizar algún tipo de indicador visual para los usuarios que aparezca en pantalla mientras dura la actua- lización (el viaje petición-respuesta-procesamiento desde el navegador al servidor y vuelta otra vez). Pero tampoco es recomendable que aparezca inmediatamente pues si la llamada es muy rápida se verá casi como un parpadeo que también desconcentrará al usuario. Para evitarnos la tarea de tener que programar algo así por nosotros mismos, asP.NeT aJaX ofrece un control llamado UpdateProgress que sirve precisamente para eso. Puedes verlo en la lista de controles de la figura 1. al arrastrarlo sobre la superficie de nuestra página asPX se mostrará como un control contenedor, de forma que podremos colocar dentro de él los elementos que deseemos que aparezcan durante una actualización asíncrona de la página. aunque hay quien prefiere un espartano cartel de texto (mira sino los indicadores de progreso que muestra GMail, que son unas simples letras sobre fondo granate), lo más habitual es usar un gráfico animado en formato GIF que muestre una sensación de progreso mientras carga la página por debajo. en la página www.ajaxload.info dispones de una interesante utilidad gratuita que te permite generar online muchos gráficos de progreso diferentes. simplemente escoges el tipo de gráfico entre una amplia lista, los colores y si quieres que sea transparente o no y el programa genera el gráfico para ti y te permite descargarlo.

genera el gráfico para ti y te permite descargarlo. Figura 8.- utilidad online para generar gráficos

Figura 8.- utilidad online para generar gráficos de progreso AJAX

A s P. net AJAX en el servidor

39

Para probar su funcionamiento vamos a añadir uno de estos controles a la página, justo a continuación del ScriptManager. Genera en la ajaxload.info un gráfico que te guste para indicar el progreso, grábalo a disco en el proyecto, refresca el explorador de soluciones y desde él arrástralo dentro del control de progreso. selecciona el control UpdateProgress y ve a sus propiedades. establece la pro- piedad AssociatedUpdatePanelID con el nombre del UpdatePanel, y su propiedad DynamicLayout como False, tal y como se ve en la figura 9.

como False , tal y como se ve en la figura 9. Figura 9.- Propiedades del

Figura 9.- Propiedades del control updateProgress

con estas propiedades lo que conseguiremos es que el indicador de progreso se muestre automáticamente durante las actualizaciones parciales del UpdatePanel1, y que el espacio que ocupa en la página se conserve incluso cuando está oculto. si establecemos DinamicLayout como True, que es su valor predeterminado, cuando el indicador aparezca reclamará su sitio en la página (ya que antes no ocupaba nada), desplazando al resto de los controles hacia abajo, lo que puede crear un efecto feo si no lo tenemos en cuenta. con el valor que le hemos dado, el espacio que ocupa está reservado y al aparecer no provoca desplazamiento alguno. La representación en marcado del control UpdateProgress es como la siguiente:

<asp:UpdateProgress ID=”UpdateProgress1” runat=”server” AssociatedUpd

atePanelID=”UpdatePanel1”>

<ProgressTemplate>

<img alt=”Cargando 16px; height: 16px” /> </ProgressTemplate> </asp:UpdateProgress>

src=”circulito.gif” style=”width:

Lo que está dentro de sus etiquetas <ProgressTemplate> (en la superficie conte- nedora si lo vemos en modo diseño) se convierte en tiempo de ejecución en el hTML correspondiente encerrado dentro de una capa con la etiqueta <div>.

40

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

Todavía queda por ver una propiedad muy importante: DisplayAfter. en ella indicaremos el tiempo en milisegundos que tardará el indicador en aparecer si la operación asíncrona no ha terminado. Por omisión este tiempo es de 500 milise- gundos. así, si la operación de postback tarda más de medio segundo en finalizar, aparecerá el indicador automáticamente para que el usuario sepa que el proceso está funcionando y que tardará un poco. al terminar la operación se ocultará también de manera automática. Para probar el indicador en nuestro ejemplo sólo nos resta simular el efecto de una operación lenta en el servidor. así que en el evento de pulsación del botón añadiremos una línea que hará que se bloquee la ejecución durante dos segundos justo antes de actualizar la hora en la etiqueta:

System.Threading.Thread.Sleep(2000)

ahora ejecuta la aplicación y pulsa el botón para mostrar la hora. ¡eh! ¿Qué pasa? No se está mostrando el indicador de progreso. La cosa no funciona el motivo es que en este caso nuestro disparador era un elemento externo al Up- datePanel (el botón está fuera y lo asociamos con un Trigger, si recuerdas). cuando el control de progreso se asocia a un UpdatePanel concreto mediante su propiedad AssociateUpdatePanelID, no es capaz de detectar el comienzo y finalización de los postback generados por disparadores externos al panel. ello se debe a que el Javascript asociado lo que hace es recorrer la jerarquía de elementos DoM que hay bajo el UpdatePanel que debe controlar, para encontrar qué control ha lanzado el repintado. como un disparador externo no está en esa jerarquía no es capaz de encontrarlo y por lo tanto el progreso no se muestra. No tendríamos problema si el botón estuviese dentro del panel. Para solucionarlo hay una acción muy simple que podemos llevar a cabo: elimi- nar la propiedad AssociatedUpdatePanelID. si tenemos en la página un control de indicación de progreso que no está asociado a un panel, lo que conseguimos es un indicador de progreso universal que se mostrará para cualquier actualización parcial que se haga en la página. si ahora ejecutas de nuevo la página verás que ya se comporta como era de espe- rar y el gráfico animado de progreso aparece al cabo de medio segundo, ocultándose automáticamente al final. De hecho es muy habitual tener un único control de indicación de progreso en la página que sirva para el proceso de repintado de cualquiera de los paneles contenidos en ésta.

8.- rEFrEScoS PArciAlES PEriódicoS

otro de los controles de aJaX disponibles es el control Timer. Éste nos permite lanzar automáticamente procesos de actualización parcial con una frecuencia perió- dica y sin que sea necesaria acción alguna por parte de un usuario. se puede utilizar para actualizar los contenidos de un UpdatePanel o por el contrario actualizar la página completa. otra aplicación interesante es la de ejecutar

A s P. net AJAX en el servidor

41

periódicamente código en el servidor aunque no sirva para actualizar nada visible en la interfaz. es un control dependiente de aJaX y aunque se use para esto último va a requerir siempre la presencia de un ScriptManager en la página (tampoco es la mejor forma de hacer algo así, todo hay que decirlo). La única propiedad interesante de este control es Interval. a través de ella se establece el número de milisegundos que servirán como periodicidad del temporiza- dor. Por defecto el periodo es de un minuto (60.000 segundos). No conviene usar un valor demasiado bajo para Interval ya que correremos el riesgo de saturar el servidor con el número de peticiones muy seguidas que se generarán. cada vez que se cumple el tiempo indicado en el intervalo se lanza un evento de servidor para el temporizador. este evento se denomina Tick. como cualquier otro evento de servidor (como el clic de un botón o cualquier otro), éste provocará un postback de la página. Y al igual que con cualquier otro control, dependiendo de donde esté colocado dentro de la página se producirá un refresco parcial o total de la misma. así, si el temporizador está dentro de un UpdatePanel con ChildrenAsTriggers= True (valor por defecto y el más habitual), el resultado será que se refrescan los contenidos del panel asíncronamente con la periodicidad especificada. si lo coloca- mos fuera de un UpdatePanel se producirá un refresco completo de la página. Por supuesto podemos asignarlo como un disparador para uno o varios UpdatePanel, en cuyo caso lo situaremos fuera y nos servirá para hacer que se refresquen parcial- mente cada cierto tiempo. si tenemos varios temporizadores en la página y todos tienen el mismo intervalo es mucho más eficiente colocar uno sólo, fuera de todos los paneles, y asignarlo como disparador para refrescarlos a todos. otra cosa a tener en cuenta es que para actuar sobre los controles de la página durante el evento del servidor, es indistinto hacerlo en el evento Tick del control o bien directamente en el evento Load de la página, ya que como sabemos durante el postback (aunque sea asíncrono) la página ejecuta su ciclo de vida normal. en el código descargable he incluido una página de ejemplo de uso del temporiza- dor que se limita a actualizar la hora en una etiqueta cada segundo, consiguiendo un reloj en funcionamiento. es evidente que algo tan sencillo es muy fácil de conseguir sin más que un poco de Javascript en el cliente, así que hacerlo con un tempori- zador es un verdadero derroche de recursos y, como decía antes, “matar moscas a cañonazos” :-), pero nos sirve para ilustrar su funcionalidad. sólo hay una última cosa importante que debemos tener en cuenta si la precisión del intervalo es importante para nosotros, y es que los tiempos pueden cambiar ligeramente en función de si el temporizador está dentro de un UpdatePanel o fuera de él. si el Timer está fuera de cualquier UpdatePanel actuando como disparador de alguno de ellos, su periodo de refresco se recarga automáticamente en cuanto lanza el evento de servidor, sin esperar a que éste regrese, ya que el código de la página que le afecta no se modifica. sin embargo cuando lo colocamos dentro de un panel, al refrescar su contenido, se regenera el código del temporizador y el tiempo comienza a contar de nuevo. esto ocurre tras haber regresado del postback asíncrono. Por lo tanto hay una diferencia con el intervalo de la otra situación que será tanto mayor cuanto más tarde en procesarse la llamada asíncrona al servidor.

42

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

Debes tenerlo en cuenta porque es una sutil diferencia pero puede ser importante en algunas aplicaciones.

9.- uNicidAd dEl ScriPTMANAgEr

al trabajar con los controles de servidor de asP.NeT aJaX hay que tener en cuenta una cosa muy importante, y es que cuando digo que debe existir un control Script- Manager en la página, me estoy refiriendo a que debe haber uno y sólo uno en todo el árbol de controles de la misma. si intentamos añadir más de un control de este tipo a la página el compilador no se quejará, pero recibiremos un error en tiempo de ejecución como el de la figura.

un error en tiempo de ejecución como el de la figura. Figura 10.- No es posible

Figura 10.- No es posible tener más de un control ScriptManager en una página

esto tiene más importancia de la que parece a primera vista y es que afectará

a la forma en la que podremos reutilizar algunas partes de nuestra aplicación. Por

ejemplo, si tenemos una o varias Master Pages deberemos decidir si el control Script- Manager se colocará en la MP o bien tendremos que colocarlo en cada una de las páginas que hagan uso de funcionalidad aJaX. Lo que no podemos es tenerlo en los dos sitios a la vez ya que en tiempo de ejecución, al fusionarse los controles de la página plantilla y de la página funcional, nos encontraremos con dos controles y se producirá un error. Lo mismo ocurre si encapsulamos funcionalidad aJaX dentro de un control de usuario y en éste incluimos el ScriptManager. si luego lo arrastramos sobre una página que ya tenga su propio ScriptManager se producirá un conflicto

y la página no funcionará. en general si nuestra aplicación hace un uso amplio de las funcionalidades aJaX, como es cada vez más habitual, lo más recomendable es incluir el ScriptManager directamente en la plantilla (Master Page). así estará disponible para todas las pá- ginas hija que hagan uso de la misma. si alguna de las páginas hija no utiliza refrescos parciales siempre podemos desactivar esta característica obteniendo una referencia al control durante la carga y usando su propiedad EnablePartialRendering, que ya hemos visto:

A s P. net AJAX en el servidor

43

Dim sm As ScriptManager = ScriptManager.GetCurrent() sm.EnablePartialRendering = false

de la clase ScriptManager nos permite obtener

una referencia a la instancia actual que se esté usando en la página, independiente- mente de que esté ubicada en la propia página, en un control o en la Master Page.

el método estático GetCurrent

10.- El coNTrol ScriPTMANAgErProXy

como hemos comentado (y veremos con detalle luego) el ScritpManager ofrece soporte para multitud de cuestiones más allá del repintado parcial de las páginas. si incluimos uno de estos controles en una Master Page y luego requerimos servicios adicionales del mismo en una de sus páginas hijas, tenemos un problema. si por ejemplo, queremos añadir una referencia a un script o a un servicio Web que es de uso específico de la página actual, dado que no podemos incluir otro control ScriptManager para hacerlo ¿cómo procederemos?. Una posible opción sería incluirlo en el que está en la Master Page, pero así tendría- mos que incluir todos los posibles servicios en la MP y ponerlos a disposición de todas las páginas, los necesiten o no, lo cual es muy ineficiente y propenso a errores. Para solucionar este problema existe el control ScriptManagerProxy. este control, disponible también en el panel de herramientas (ver figura 1), se arrastra a la página como otro cualquiera y actúa como un apéndice del script Manager único que está en la Master Page para añadirle las características adicionales que necesitemos. Por ejemplo, este fragmento muestra la sintaxis de uno de estos controles que se usa para incluir en la página, en la sección <scripts> (luego la estudiaremos), un código de script específico que se necesita para dotarla de alguna funcionalidad de lado cliente:

<asp:ScriptManagerProxy ID=”ScriptManagerProxy1” runat=”server”> <Scripts> <asp:ScriptReference Path=”scriptEspecifico.js” /> </Scripts> </asp:ScriptManagerProxy>

este tipo de proxy se puede utilizar también en controles de usuario que luego van a ser utilizados en páginas que ya tiene un ScriptManager, bien porque lo incluyan directamente, bien porque lo tenga la Master Page correspondiente. Debes recordar bien este control porque lo usarás mucho más de lo que te ima- ginas en cualquier aplicación grande.

11.- gESTióN dE ErrorES AJAX

en condiciones normales todo va a funcionar de maravilla. Pero la dura realidad es que siempre, en algún momento, pasa algo que hace que las cosas fallen. si durante un postback asíncrono se produce un error en el servidor ¿cómo podemos gestionarlo?.

44

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

vamos a crear una pequeña aplicación de ejemplo que produzca errores para ver cómo podemos gestionarlos. crea una nueva página en el proyecto, “erroresajax.aspx”, y añádele un Script- Manager, un UpdatePanel y dentro de éste un simple botón con el texto “Provocar error”. en el manejador del evento click de este botón lanza una excepción así:

Throw New Exception(“Error provocado a mano!!”)

ahora ejecútala pulsando cTrL + F5 para evitar que se trabaje en modo depu- ración, pues en ese caso saltaría un punto de interrupción en visual studio y no verías cómo funciona en la realidad, cuando esté en producción. verás que el error en el lado servidor se traduce en el navegador en forma de un error de Javascript. si tienes la depuración de Javascript activada verás un mensaje como el de la figura 11. como se puede comprobar en dicha figura, el mensaje descriptivo del error original se visualiza en el error de Javascript también.

original se visualiza en el error de Javascript también. Figura 11.- Error de JavaScript provocado en

Figura 11.- Error de JavaScript provocado en el servidor

en este caso el error, al ser manual, tiene una descripción amigable y neutra, y no pasa nada porque se vea. sin embargo esta situación no es la más recomendable. Una de las reglas básicas de seguridad de aplicaciones dice que no se debe dar información técnica de errores a usuarios finales. Generalmente los errores que se producirán en el servidor incluyen en su descripción detalles internos de la aplica- ción, por ejemplo nombres de campos en bases de datos o rutas en disco, que podrían dar información valiosa a posibles atacantes. Por este motivo se recomienda gestionar siempre los errores y devolver al usuario un mensaje más amigable, sin dar detalles internos. Para ello el control Script- Manager nos ofrece el evento AsyncPostBackError, en el que podremos gestionar cualquier tipo de excepción que se produzca durante un postback asíncrono.

A s P. net AJAX en el servidor

45

A s P. net AJAX en el servidor 45 Figura 12.- Evento para gestión de errores

Figura 12.- Evento para gestión de errores en postbacks asíncronos.

como segundo argumento de este evento tenemos un objeto de tipo Async- PostbackErrorEventArgs. su única propiedad interesante, Exception, nos permite acceder a la excepción producida y trabajar con ella para actuar en consecuencia. en nuestro ejemplo vamos simplemente a poner un mensaje más amigable inde- pendientemente de cuál sea la excepción producida:

Protected Sub ScriptManager1_AsyncPostBackError(ByVal sender As Object, ByVal e As System.Web.UI.AsyncPostBackErrorEventArgs) Handles

ScriptManager1.AsyncPostBackError

ScriptManager1.AsyncPostBackErrorMessage = “Se ha producido un error en la operación. Si persiste contacte con el administrador”

End Sub

Utilizamos la propiedad AsyncPostBackErrorMessage del ScriptManager para asignar un mensaje más amigable:

del ScriptManager para asignar un mensaje más amigable: Figura 13.- El mensaje amigable en el error

Figura 13.- El mensaje amigable en el error de lado cliente

No obstante, sería más adecuado que se mostrase de una forma más integrada dentro de la página, y no traducido a una excepción de Javascript.

46

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

La parte cliente de asP.NeT aJaX ofrece soporte para interceptar de manera

sencilla los distintos eventos en el ciclo de vida de las peticiones asíncronas. vamos

a sacarles partido para detectar desde Javascript que se ha producido un error

durante un evento de servidor asíncrono, y mostrar al usuario un mensaje dentro de la propia página, mediante capas. en la siguiente figura se puede observar el

aspecto del mismo.

la siguiente figura se puede observar el aspecto del mismo. Figura 14.- Mensaje de error personalizado

Figura 14.- Mensaje de error personalizado

se muestra el mensaje de error dentro de una pequeña capa flotante, y se oscurece

la

página para darle más protagonismo al mensaje, e impedir al mismo tiempo que

el

usuario pueda pulsar sobre el resto de los elementos. es una forma sencilla de

simular un diálogo modal dentro de una página usando únicamente capas y estilos. el efecto de transparencia se consigue con un gráfico GIF semitransparente puesto como fondo de una capa.

Para conseguirlo se debe incluir en la página un poco de código Javascript que se encargue de interceptar un posible error al volver del postback asíncrono, y que luego se encargue de mostrar y ocultar la capa flotante sobre la que se mostrará

el mensaje.

A s P. net AJAX en el servidor

47

Nota:

esta parte es código de lado cliente, que forma parte de otro capítulo del libro, pero lo he in- cluido aquí porque está directamente relacionado con la gestión de errores. No vamos a ver los detalles del código Javascript utilizado para conseguir toda la funcionalidad. Nos centraremos únicamente en la parte relacionada con la gestión del error, que es la que nos ocupa. Puedes ver el código completo del ejemplo en el ZIP con las demos del libro.

La clase PageRequestManager proporcionada en el lado cliente por asP.NeT aJaX sirve para acceder a toda la funcionalidad de postbacks asíncronos. Podemos obtener una referencia a la clase actualmente utilizada para realizar las peticiones con esta expresión Javascript:

Sys.WebForms.PageRequestManager.getInstance()

el método add_endRequest() de esta clase sirve para añadir nuevos manejadores al evento de finalización de llamada asíncrona. es decir, que podemos ser notificados automáticamente de cuando un postback asíncrono regresa. si definimos una función Javascript con el nombre de, por ejemplo, EndRequesthandler, podemos usarla para interceptar el evento y así poder trabajar con los datos de la petición:

Sys.WebForms.PageRequestManager.getInstance().add_

endRequest(EndRequestHandler);

La función recibe dos parámetros, al más puro estilo .NeT aún siendo Javascript, siendo el primero de ellos el “sender” y el segundo una referencia a un objeto de la clase EndRequestEventArgs. esta clase sólo tiene dos propiedades interesantes:

Error: contiene información del error. como Javascript no tiene propiedades, por convención se debe leer su contenido llamando al método get_error(). La clase error devuelta tiene tres propiedades (message, number y name) que nos permiten averiguar respectivamente el mensaje, el número y el nombre del error.

errorHandled: se usa para indicar a la infraestructura de aJaX que el error ya lo hemos gestionado nosotros y que por lo tanto no debe dejar que se produzca. se escribe en ella, por convención, llamando al método:

set_errorHandled().

en el código de ejemplo descargable están todos los detalles comentados, pero basta indicar que lo que se hace es comprobar en un condicional si la propiedad Error contiene o no una referencia válida, en cuyo caso se muestra el mensaje de la figura anterior, y se indica que ya hemos gestionado nosotros el problema, para evitar que se manifieste como una excepción de Javascript. Descárgate y échale un vistazo al código de ejemplo.

48

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

en aplicaciones que no usan aJaX lo habitual es que gestionemos los errores

usando alguna página especial, que configuramos en nuestro web.config para que

la infraestructura de asP.NeT se encargue de mostrarla. Por ejemplo, podríamos

tener esta configuración:

<customErrors mode=”RemoteOnly” defaultRedirect=”errorGenerico.aspx”> <error statusCode=”500” redirect=”ErrorServidor.aspx” /> <error statusCode=”403” redirect=”Prohibido.aspx” /> <error statusCode=”404” redirect=”NoEncontrado.aspx” /> </customErrors>

así, cuando se produzca un error en el servidor (código de estatus hTTP igual a 500) se mostrará automáticamente al usuario la página “errorservidor.aspx”. De similar manera se comportaría la aplicación ante intentos de acceso no autorizados

(403) o páginas no encontradas (404), redirigiendo a las páginas correspondientes. si

se produce cualquier otra circunstancia no contemplada específicamente se muestra

una página de error genérica “errorGenerico.aspx”. Por defecto el ScriptManager trata los errores producidos en el servidor para que sean totalmente compatibles con el comportamiento indicado en el web.config. Por lo tanto si hemos definido una página especial para errores de servidor en nuestra configuración y se produce una excepción durante un postback asíncrono, la infraestructura de asP.NeT aJaX se encarga de que todo funciones de la manera normal, redirigiendo a la página indicada. Debemos tener en cuenta pues, que en caso de haber configurado páginas de error personalizadas, no recibiremos jamás en el cliente notificaciones de los errores, y las técnicas mostradas anteriormente no funcionarán. La propiedad AllowCustomErrorsRedirect del ScriptManager sirve para ajustar este comportamiento. Por defecto vale True y obtenemos el funcionamiento habi- tual. si la establecemos a False se hará caso omiso del web.config para los errores producidos durante repintados parciales. en el ejemplo descargable de la Web puedes quitar los comentarios en el web.config para habilitar una página personalizada para los errores 500. verás cómo a partir de ese momento el diálogo de la figura 14 se deja de mostrar y aparece la página de error que se ha definido.

12.- iNcoMPATibilidAdES dE AJAX

a la hora de usar el repintado parcial de los controles y las llamadas asíncronas

debemos tener en cuenta algunas limitaciones. son pocas pero pueden impactar negativamente en nuestros desarrollos si no las hemos considerado de antemano.

A s P. net AJAX en el servidor

49

algunos controles Web de asP.NeT, dado su modo de trabajar, no son compa- tibles con las actualizaciones parciales de la página y, por consiguiente, no están diseñados para funcionar dentro de un control UpdatePanel. La mayoría no ofrecen problemas, pero hay algunos que presentan incompatibilidades que, o bien impiden su funcionamiento o limitan alguna de sus características:

Los controles de envío de archivos al servidor: FileUpload y HtmlInputFile, que sólo funcionarán de modo nativo si se realiza un postback síncrono común. en el mercado hay algunos controles de publicación de archivos que soportan asincronismo (por ejemplo el de Subgurim, gratuito y descargable desde http://fileuploadajax.subgurim.net), si bien no usan UpdatePanel para conseguirlo.

Los controles TreeView y Menu.

el control Substitution.

Los controles Login, PasswordRecovery, ChangePassword y CreateUserWi- zard cuyo contenido no ha sido convertido previamente en plantillas editables. es una limitación con poco impacto porque, o bien se convierten a plantillas o bien se pueden utilizar las aPI de seguridad directamente desde Javascript para conseguir el mismo efecto, como veremos en el próximo capítulo.

Los controles GridView y DetailsView cuando su propiedad EnableSortin- gAndPagingCallbacks es True. Por defecto no tienen activada esta propiedad por lo que no hay problema. además, esta propiedad se utiliza precisamente para conseguir el mismo efecto que con el UpdatePanel (sólo que utiliza otras técnicas diferentes), por lo que no hay problema alguno en desactivarla dentro del panel. No se puede considerar una verdadera limitación.

adicionalmente si utilizas visual studio 2005 con asP.NeT 2.0, en esta versión antigua del entorno de desarrollo y del Framework no están soportados en aJaX los controles relacionados con WebParts. Tampoco funcionarán los controles de validación, si bien se pueden hacer compatibles con sólo desconectar la validación de lado cliente (propiedad EnableClientScript = False). No existen estos problemas de compatibilidad con estos controles en versiones de visual studio superiores a la 2008, incluida ésta. Todos los demás controles funcionan dentro de los controles UpdatePanel. sin embargo, en algunas circunstancias, un control podría no funcionar como era de esperar si lleva a cabo alguna de estas acciones:

registrar scripts en la página usando métodos de la clase ClientScriptManager. esta clase se abandona en el caso de aplicaciones aJaX a favor de los méto-

50

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

dos equivalentes que ofrece el propio control ScriptManager, compatibles con las actualizaciones parciales. si necesitas registrar scripts como parte de un postback usa éstos últimos. Lo veremos con detalle en el próximo capítulo.

el uso directo de casi cualquier método de la clase HttpResponse no se llevará bien en general con las llamadas asíncronas. Por eso debemos evitar la llamada directa a los métodos: BinaryWrite, Clear, ClearContent, ClearHea- ders, Close, End, Flush, TransmitFile, Write, WriteFile y WriteSubstitution. especialmente habitual es la generación directa de scripts o etiquetas hTML durante el repintado de un control o durante el procesado de un evento me- diante llamadas al método Response.Write, que es algo que debemos evitar.

13.- AJAX coNTrol ToolkiT

Microsoft, conjuntamente con la comunidad de desarrolladores, ha creado el Kit de controles aJaX o AJAX Control Toolkit. se trata de un conjunto de más de 30 controles que permiten extender y dotar de funcionalidad extra avanzada a controles comunes de asP.NeT. La funcionalidad de estos controles se centra en el lado del cliente, es decir, en mejorar las características de los controles normales cuando ya están renderizados en el navegador, pero se añaden y configuran desde el servidor, por eso los he incluido en este capítulo. así, por ejemplo, gracias al Toolkit es muy sencillo hacer cosas como añadir un calendario desplegable a un TextBox para facilitar al usuario que escoja una fecha, o mostrar diálogos de confirmación integrados en la página, mejorar el aspecto de los mensajes de validación, crear animaciones, tener un editor hTML, etc. Por el mero hecho de utilizar estos controles obtendremos grandes mejoras en la usabilidad de las interfaces de nuestras aplicaciones Web asP.NeT. Los podemos usar en combinación con los repintados parciales o de manera completamente inde- pendiente, o lo que es lo mismo, requieren la existencia de un control ScriptManager en la página, pero no es necesario introducirlos dentro de un UpdatePanel ni utilizar éste ni ningún otro de los controles asP.NeT aJaX que hemos estudiado. su uso es extremadamente sencillo. Lo más complicado sea tal vez instalar el Toolkit, así que vamos a explicar cómo obtenerlo y ponerlo en marcha en nuestro sistema. el aJaX control Toolkit está disponible para descarga gratuita en codePlex (el directorio de proyectos open source de Microsoft), y en concreto en la siguiente dirección: http://ajaxcontroltoolkit.codeplex.com/Release/.

A s P. net AJAX en el servidor

51

A s P. net AJAX en el servidor 51 Figura 15.- Página de descarga del AJAX

Figura 15.- Página de descarga del AJAX control Toolkit

La última versión allí disponible funcionará sin problemas tanto en visual studio 2008 como en visual studio 2010. si estás usando visual studio 2005 con la versión 2.0 de la plataforma deberás buscar, un poco más abajo, las versiones anteriores específicas para este entorno. como se observa en la figura 15 la página ofrece tres variantes para descargar.

La primera versión “Binary” contiene únicamente las DLL necesarias para

poder trabajar con el control desde visual studio. es la variante que necesi- tamos si queremos distribuir el Toolkit con alguna de nuestras aplicaciones

o para instalar en un servidor en el que se vaya a utilizar éste con una aplicación allí desplegada.

La variante “source” contiene, además de los binarios compilados, todo el

código fuente de los diferentes controles. es una gran fuente de información

y

estudio si estamos interesados en cómo construir este tipo de controles. es

la

más apropiada para ser utilizada en nuestro equipo de desarrollo.

52

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

Por fin la variedad “scriptFilesonly” contiene únicamente el código Javascript que utilizan los controles para su funcionalidad en el navegador. se trata de la funcionalidad de los controles en su estado puro, para usar directamente en el navegador. esta es la variante que usarán los programadores más avanzados que emplearán directamente código Javascript para instanciar los diferentes Behaviours de estos controles en sus páginas.

en la mayor parte de los casos lo mejor es bajarse la primera o segunda va- riedad. Una vez descargado el ZIP correspondiente, descomprímelo en una carpeta de tu disco duro en la que vaya a estar disponible todo el tiempo, ya que una vez añadidos los controles a visual studio los usaremos siempre desde allí. La variante “Binary” descomprimirá ya directamente la DLL y carpetas asociadas que necesitamos. en el caso de la descarga con código fuente, la DLL que usaremos está dentro de la carpeta “Binaries” una vez descomprimido el ZIP. Dentro de la carpeta de binarios del Toolkit hay una DLL, AjaxControlToolkit.dll, que contiene toda la funcionalidad

de los controles, así como una serie de carpetas con identificadores de idiomas (como

que contienen ensamblados satélites con los textos adaptados

“es”, “ar”, “cs”, “de”

a cada uno de estos idiomas. ahora lanza visual studio y crea una nueva aplicación Web o abre cualquier aplicación Web que tengas ya hecha. edita una página asPX cualquiera para poder desplegar la barra de controles Web, como si fueras a añadir uno sobre la página. al desplegar la barra de herramientas pulsa con el botón derecho sobre alguna zona libre de ésta y en el menú contextual añade una nueva sección. Llámala “aJaX control Toolkit”. vuelve a pulsar con el botón derecho dentro del área vacía de esta nueva sección y elige la opción “elegir elementos” (“choose Items” en la versión en inglés del entorno):

)

Items” en la versión en inglés del entorno): ) Figura 16.- Añadiendo controles a la nueva

Figura 16.- Añadiendo controles a la nueva sección que hemos creado.

A s P. net AJAX en el servidor

53

al hacer esto aparecerá, tras una cierta espera, un diálogo como el de la figura 17, en el que podremos elegir qué controles .NeT queremos que estén disponibles desde la barra de herramientas, y en concreto dentro de la sección actual.

de herramientas, y en concreto dentro de la sección actual. Figura 17.- diálogo de gestión de

Figura 17.- diálogo de gestión de controles

Lo único que resta por hacer es, con el botón Browse de la figura, localizar la DLL del aJaX control Toolkit (recuerda: AjaxControlToolkit.dll, en la carpeta correspondiente de la descarga anterior) y aceptar para que los controles se añadan automáticamente a la barra de herramientas.

Nota importante:

en visual studio 2010 este proceso fallará con un mensaje similar a este:

Could not load file or assembly ‘file:///C:\AjaxControlToolkit\AjaxControlToolkit.dll’ or one of its dependencies. Operation is not supported. (Exception from HRESULT:

0x80131515)

el motivo es el tratamiento especial que hace la versión 4.0 de .NeT de los ensamblados baja- dos de Internet. el sistema operativo marca con un indicador especial a los ensamblados des- cargados de cualquier recurso remoto (Internet o una carpeta compartida en la red local). De este modo pueden ser reconocidos como posibles amenazas de seguridad al proceder, a priori, de un origen no confiable como es Internet. El sistema operativo los trata de una forma dife-

54

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

rente debido a esto aunque los tengamos copiados ya en una carpeta local. sin embargo
rente debido a esto aunque los tengamos copiados ya en una carpeta local. sin embargo .NeT
en sus versiones anteriores a la 4.0 hacía caso omiso de esta información sobre el origen y al
estar ubicados en local los trataba como ensamblados confiables. Como mejora de seguridad en
.NeT 4.0 se tiene en cuenta esta particularidad y limita la capacidad de todos estos .exe o .dll
que se descarguen directamente o dentro de un ZIP desde una ubicación remota. Por este moti-
vo la DLL del aJaX control Toolkit no es capaz de cargarse en el entorno de visual studio.
Para solucionarlo lo que tenemos que hacer es desbloquear su funcionalidad. Para ello localiza
la DLL en tu disco duro y en sus propiedades verás un botón “Desbloquear” que sirve preci-
samente para esto (ver figura 18). Necesitarás permisos de administrador para que el botón
funcione, así que si estás en una carpeta de sistema (como por ejemplo la de Archivos de Pro-
grama) mueve antes la DLL a otro lugar, cambia este atributo y devuélvela a su sitio original.
Figura 18.- desbloqueo de ensamblado descargado desde sitio remoto.
Ahora repite la operación anterior y verás como el problema desaparece y los controles se incor-
poran a tu barra de herramientas.

Una vez terminada la operación verás que en tu barra de herramienta aparecen multitud de controles nuevos, como se puede ver en la figura 19.

A s P. net AJAX en el servidor

55

A s P. net AJAX en el servidor 55 Figura 19.- los controles del AJAX control

Figura 19.- los controles del AJAX control Toolkit

aunque tengamos todos esos controles en la barra de herramientas, lo cierto es que, al trabajar con visual studio 2008 o visual studio 2010, no vamos a usarlos casi nunca desde ella. en visual studio 2005 sí que será necesario arrastrarlos desde ahí. en visual studio 2008 o superior las extensiones que ofrece el Toolkit están integradas con el entorno una vez las hayamos instalado. así, al seleccionar un control en la página como un TextBox u otro cualquiera, éste presentará entre sus tareas asociadas una nueva acción llamada “añadir extensor”:

asociadas una nueva acción llamada “añadir extensor”: Figura 20.- Acción de un control para extenderlo con

Figura 20.- Acción de un control para extenderlo con el Toolkit

al pulsar sobre la acción se abre un diálogo en el cual podemos elegir qué acción extensora, proporcionada por los diferentes controles del Toolkit, queremos añadir a nuestro control. Para cada control ofrece las acciones más apropiadas. Por

56

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

ejemplo en la figura 21 estamos añadiendo un calendario desplegable a un control TextBox, de forma que cuando los usuarios lo seleccionen se mostrará para ayudar a introducir fechas.

lo seleccionen se mostrará para ayudar a introducir fechas. Figura 21.- Extensión de un Textbox con

Figura 21.- Extensión de un Textbox con un calendario desplegable.

esta extensor se corresponde con la funcionalidad del control CalendarExtender de la barra de herramientas (lo puedes identificar hacia la mitad de la columna de la derecha en la figura 19. a la hora de ejecutar la aplicación, todo el comportamiento que se observa en el navegador (en este caso la aparición del calendario y su funcionalidad) se pro- porciona directamente desde el lado cliente, mediante Javascript. No hay postbacks al servidor para ofrecer estas características. La funcionalidad es compatible con la mayor parte de los navegadores modernos (Internet explorer, Firefox, safari

los navegadores modernos (Internet explorer, Firefox, safari Figura 22.- El extensor para calendarios en funcionamiento

Figura 22.- El extensor para calendarios en funcionamiento básico

A s P. net AJAX en el servidor

57

Por otro lado en la superficie de diseño en visual studio, a simple vista no ofrece ningún signo distintivo de que el control está usando esta extensión. si desplegamos las acciones para el control, ahora además de tener la posibilidad de añadir extensio- nes (podemos añadir cuantas necesitemos), también está la opción para quitar alguna de las que se están usando. otro signo visible de que el control está siendo extendido es que en sus propie- dades ahora hay una nueva sección denominada “extensores” que ofrece, agrupadas, las propiedades que controlan el comportamiento de cada uno de estas extensiones. en la figura siguiente se ven las propiedades para el calendario desplegable, con las que podemos amoldar su forma de funcionar a nuestras necesidades.

amoldar su forma de funcionar a nuestras necesidades. Figura 23.- Propiedades de controles extensores en realidad

Figura 23.- Propiedades de controles extensores

en realidad la mayor parte de los controles del Toolkit son muy fáciles de utilizar y en esta obra no vamos a entrar en detalles sobre el funcionamiento particular de cada uno de ellos. en la dirección:

http://www.asp.net/ajax/ajaxcontroltoolkit/samples/

se puede encontrar una aplicación de referencia en la que, uno a uno, se presenta cada control, su sintaxis y sus posibilidades. si visitas la página podrás verlos en funcionamiento, y conocer los detalles de cómo sacarle partido.

58

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

tecnologías A s P. net 4.0 (saltando desde la versión 2.0) Figura 24.- Página de demostración

Figura 24.- Página de demostración y documentación del control Toolkit

esta misma aplicación de ejemplo se incluye dentro de la carpeta “sampleWeb- site” de la variante “source” de las descargas del Control Toolkit, así que puedes ejecutarla en local y mirar cómo está hecho cada ejemplo para aprender más todavía sobre ellos. en el código de ejemplo descargable desde la web del libro he incluido una pequeña página de ejemplo (“controlToolkit.aspx”) en la que un cuadro de texto se extiende con un calendario y una marca de agua para indicar el formato a los usuarios. el botón de envío se extiende con un control ConfirmButtonExtender de manera que nos pregunte si queremos enviar los datos al pulsarlo, y los dos vali- dadores incluidos se han extendido con sendos controles ValidatorCalloutExtender para dotarlos de mayor vistosidad. ejecútalo para ver cómo, con sólo añadir estos extensores y sin código adicional, la interfaz se puede mejorar mucho.

y sin código adicional, la interfaz se puede mejorar mucho. Figura 25.- un ejemplo de validador

Figura 25.- un ejemplo de validador mejorado

Merece la pena dedicarle un tiempo para conocer bien el aJaX control Toolkit, ya que mejorarán mucho la calidad de tus interfaces con un mínimo esfuerzo.

cAPíTulo 4
cAPíTulo
4

A s P. net AJAX en el navegador

con todo lo visto hasta ahora en el capítulo anterior, ya tenemos herramientas sufi-

cientes para desarrollar impactantes aplicaciones Web de alta velocidad de respuesta,

sacando partido a los repintados parciales. Pero

respuestas rápidas en la interfaz? ¿es realmente todo tan fácil como parece? el ser humano no se caracteriza precisamente por la mesura en sus acciones. La propensión natural en cualquier ámbito es a abusar de aquellas cosas que nos gustan o nos reportan beneficio sin pararnos mucho a pensar en las consecuencias, sobre todo si son fáciles y parecen no tener efectos negativos. Por ello cuando los programadores Web con asP.NeT, acostumbrados a los postback, descubren las posibilidades que les otorga el binomio ScriptManager-UpdatePanel, lo habitual es que empiecen a usarlo en todas partes. al fin y al cabo es muy fácil y “no hay que saber demasiado”: se arrastran un par de controles a una página normal y todo funciona de maravilla. además, toda aplicación Web moderna que se precie debe ofrecer en la medida de lo posible este tipo de funcionalidad. el resultado habitual es que se colocan varios controles UpdatePanel en todas las páginas o, peor todavía, se mete un gran UpdatePanel en la página que contiene a todos los demás controles (créeme, lo he visto). Tras desarrollar toda la funcionalidad se prueba la aplicación y todo funciona de maravilla: rápido, sin molestos refrescos de la página y con un aspecto super- profesional. Los problemas vienen cuando la aplicación se pone en producción en el servidor. en las primeras pruebas se nota todo algo más lento pero no parece realmente preocupante. al fin y al cabo estamos accediendo a través de Internet, no de la red local, y es normal que la velocidad sea algo menor. Pasan los días y las semanas. a medida que los usuarios de la aplicación aumentan, ya que tenemos más clientes o visitas, la cosa empieza a ir cada vez peor. Llega un punto en el que trabajar con la aplicación Web se vuelve insoportable de lo lenta que va. Miramos nuestro código para ver si tenemos alguna consulta a la base de datos que nos esté cargando el servidor y miles de posibilidades más, pero el problema de rendimiento no aparece. ¿Qué está pasando aquí? Lo que está pasando es que, a pesar de la aparente ligereza de las llamadas asíncronas con los Updatepanel, lo cierto es que (como ya se ha dicho) cada postback

¿tendremos siempre realmente

60

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

asíncrono es un postback completo. esto implica que se envía toda la información de todos los controles de la página al servidor, incluyendo el ViewState. en la página se recrea el árbol de controles, se procesan todos y cada uno de los eventos de éstos así como los de la página. al terminar se devuelve el nuevo ViewState y el nuevo hTML para renderizar. La infraestructura de aJaX se queda sólo con el hTML correspondiente al UpdatePanel que se va a refrescar, pero en realidad se ha tenido que mover la página completa desde el cliente (el navegador) al servidor. así que, como dicen los anglosajones: “There’s no such thing as a free lunch”, es decir, que nadie da algo a cambio de nada. Y en este caso la máxima es cierta también. No quiero decir que las técnicas que hemos visto hasta ahora sean dañinas para el rendimiento. De hecho se pueden aplicar en sitios más o menos grandes sin pro- blema. No obstante no se deben utilizar de cualquier manera, y en muchos casos habrá que medir bien el uso que se hace de ellas. su empleo indiscriminado sin entender realmente lo que está pasando por debajo, conduce a muchos problemas de rendimiento. si tenemos claros los conceptos y buscamos la forma de hacer las cosas lo mejor posible en cada circunstancia nos ahorraremos muchas frustraciones y problemas en el futuro. es por esto que Microsoft no concibió asP.NeT aJaX únicamente como un puñado de controles de servidor, sino que éstos se apoyan en una rica parte de programación en el lado cliente, de la que nosotros podremos aprovecharnos también para conseguir aplicaciones ágiles y optimizadas. este capítulo profundiza en las principales técnicas de trabajo en el lado del na- vegador conducentes a mejorar mediante Javascript las características de las páginas aJaX así como su rendimiento. Para seguir los próximos apartados es recomendable que tengas unos conoci- mientos fundamentales del lenguaje Javascript así como de hTML y manipulación del DoM del navegador. si no cumples estos requisitos puede que algún ejemplo concreto te cueste comprenderlo, pero si investigas un poco el código por tu cuenta no tendrás problema al final. vamos allá

1.- rETrollAMAdAS dE rEd A MéTodoS ESTÁTicoS

Imagínate el siguiente ejemplo: tienes un formulario Web que contiene una rejilla llena de datos, varios controles de texto para entrada de información, algunos bo- tones, listas desplegables para filtrado así como algunas etiquetas y controles de menor entidad. en una esquina hay una etiqueta que muestra un dato importante, un simple número (por ejemplo el stock en un almacén), y que el usuario de vez en cuando le gustaría ver actualizado. Dado que el resto de la página permanece inalterado, sólo por actualizar esa pequeña etiqueta no vamos a hacer un postback al servidor y recargar toda la enorme página ¿verdad?. aparentemente se impone el uso de un útil UpdatePanel para con-

A s P. net AJAX en el navegador

61

seguir un repintado parcial de la etiqueta. así que allá vamos nosotros: lo colocamos rodeando a la etiqueta, establecemos el botón de refresco como disparador “et voilà”. Listo para poner en producción. Lo malo es que no nos hemos dado cuenta de que, cada vez que se refresca la pequeña etiqueta, en realidad estamos procesando la página completa en el servidor y transmitiendo a través de la red enormes cantidades de información. sólo el ViewState de la página puede ocupar cientos de Kb. el resultado: un rendimiento nefasto cuando lo ponemos al alcance de los usuarios.

1.1.- Análisis de tráfico con un updatePanel

vamos a ver el efecto con un ejemplo muy sencillo. Desarrollaremos el mismo ejemplo con una página común que utiliza el control UpdatePanel, y luego ve- remos lo mismo usando código Javascript super-eficiente para comprender las diferencias. ello nos dará una idea muy buena de cuándo merece la pena aplicar una u otra técnica. el proyecto completo está disponible en el ZIP con los ejemplos de código que puedes descargar de la web de Krasis Press. Lo encontrarás en la carpeta “aJaX_ servicioscliente”. abre visual studio y crea una nueva aplicación Web. elimina la página por de- fecto “Default.aspx” y añade una nueva con el nombre “horaconUpdatePanel.aspx”. arrastra sobre ella un ScriptManager, un UpdatePanel y, dentro de éste último, una etiqueta (roja y con letras grandes) y un botón. el aspecto de la página debería ser similar al de la figura 1.

de la página debería ser similar al de la figura 1. Figura 1.- Aspecto de nuestra

Figura 1.- Aspecto de nuestra página de ejemplo

como código para el evento de servidor que responde a la pulsación del botón vamos a escribir simplemente una línea que mostrará, dentro de la etiqueta, la hora actual en el servidor:

Protected Sub cmdDameHora_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdDameHora.Click lblHora.Text = DateTime.Now.ToLongTimeString() End Sub

62

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

Ya está todo lo necesario. Ahora lanza la aplicación y pulsa el botón varias ve - ces. Verás que la hora se muestra actualizada en la etiqueta a toda velocidad y sin problema alguno. Vamos a ir más allá de la superficie y veamos qué está pasando por debajo. Para ello vamos a utilizar una de mis herramientas favoritas: Fiddler. Esta utilidad gratuita ha sido creada por Eric Lawrence de Microsoft (aunque sin soporte oficial por la compañía). Actúa como proxy en todas las peticiones Web que se hacen en el equipo y permite inspeccionarlas de forma que podamos conocer sus datos, la información devuelta en ellas, modificarlas al vuelo, y un sin fin de utilidades más. Se puede descargar desde www.fiddler2.com. Si ponemos en marcha Fiddler y pulsamos el botón que actualiza la hora en la etiqueta veremos que se produce una llamada al servidor. Si la inspeccionamos para ver sus contenidos obtenemos los datos que muestra la figura 2:

sus contenidos obtenemos los datos que muestra la figura 2: Figura 2.- contenidos de la llamada

Figura 2.- contenidos de la llamada al servidor con updatePanel

aquí vemos que la llamada, dado que debe enviar el ViewState de los controles, lleva 268 bytes de información. Y eso en esta página tan sumamente simple. Ima-

A s P. net AJAX en el navegador

63

gínate lo que enviará en páginas más complejas como la del ejemplo al principio de este epígrafe. Pero eso no es todo. La respuesta que contiene el nuevo Viewstate así como diversa información necesaria para actualizar el UpdatePanel ocupa 708 bytes. es decir que en total, para actualizar una información -la hora- que ocupa úni- camente 8 caracteres (o sea, 8 bytes) estamos generando un tráfico de 976 bytes, es decir, ¡122 veces mayor de lo necesario!. además a esto hay que añadir la sobrecarga en el servidor, en el que se ha generado el árbol de controles y se han ejecutado todos eventos de la página y sus controles tan sólo para poder asignarle el valor a la etiqueta. esto usa procesador y memoria y reduce la escalabilidad de la aplicación. Parece que al final lo de usar siempre un UpdatePanel no es tan buen negocio después de todo.

1.2.- Ejemplo optimizado con retrollamadas de red a métodos estáticos

está claro que en este ejemplo, a pesar de lo espectaculares que son los números relativos, el impacto es mínimo. Y en muchos otros casos puede que también sea así, y el uso de un UpdatePanel está más que justificado gracias a la productividad que obtenemos. No obstante vamos a ver cómo podemos crear una versión de esta misma página que esté optimizada y nos genere el mínimo tráfico posible. así aprenderemos a solventar casos más graves en los que esta sobrecarga adicional no esté justificada

o nos produzca problemas graves de rendimiento. Para ello vamos a explicar lo que se conoce como Retrollamadas de Red a Métodos Estáticos, o de manera más común, Métodos de Página. esta técnica, como su propio nombre indica, nos permite definir dentro de la página uno o más métodos que serán accesibles directamente a través de Internet desde el navegador, siendo sólo necesario el uso de código Javascript. De este modo en lugar de llamar a la página completa, que es lo que hacíamos antes, ahora llama- remos exclusivamente al método en cuestión, obteniendo una respuesta optimizada como enseguida veremos con el ejemplo. añade otra página al proyecto con el nombre “MetodosDePagina.aspx”. arrastra

a su superficie de diseño un control ScriptManager. vete a la vista de código fuente

de la página e introduce una etiqueta <div> para definir una capa hTML. otórgale el nombre “divhora” y en su estilo asígnale un color rojo y un tamaño de texto grande. Nos servirá para mostrar la hora y hará las veces de la etiqueta en nuestra versión optimizada del ejemplo anterior. arrastra también, desde el grupo hTML, un botón hTML normal. en su atributo onclick asígnale el código Javascript “Mos- trarhora();”, que enseguida definiremos.

64

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

el código final debería tener este aspecto:

versión 2.0) el código final debería tener este aspecto: Figura 3.- código hTMl de nuestro ejemplo

Figura 3.- código hTMl de nuestro ejemplo optimizado

a excepción del ScriptManager no estamos utilizando controles de servidor, pero

en cualquier caso daría igual porque, como veremos, ya no será necesario enviar el ViewState ni otros elementos de formulario que hubiese en la página asPX. en el archivo Code Beside de la página (el .vb o .cs correspondiente) vamos a definir una sencilla función llamada DameHora() que devolverá una cadena con la hora actual en el servidor:

<WebMethod()> _ Public Shared Function DameHora() As String Return DateTime.Now.ToLongTimeString() End Function

al igual que si de un miembro de un servicio Web asMX se tratara decoramos este método con un atributo WebMethod. esto es indispensable para llamarlo desde el lado cliente. otra cuestión importante a tener en cuenta es que el método que definamos para

ser llamado desde el cliente debe ser un método estático (o Shared en visual Basic). el motivo es que así no será necesario instanciar la página, lo que provocaría la misma carga que en el caso anterior al reproducir el árbol de controles, etc

el último detalle que nos queda es asignar a True la propiedad EnablePageMe-

thods del ScriptManager, que por defecto contiene un False.

Nota:

esta propiedad hay que establecerla sobre el verdadero ScriptManager que vayamos a uti- lizar. No se puede establecer en un ScriptManagerProxy por lo que si el nuestro está en un Master Page debemos marcarlo en ésta directamente y quedará habilitado para todas las páginas que la usen.

A s P. net AJAX en el navegador

65

cuando se cree el código hTML final resultante de ejecutar la página, la pro- piedad EnablePageMethods hará que se genere automáticamente en el navegador el código Javascript necesario para llamar al método de la página. De hecho la llamada en Javascript será tan directa y fácil como escribir:

PageMethods.NombreMetodo

siendo NombreMetodo el nombre de alguno de los métodos de página que hayamos definido. a este método de Javascript se le pasan dos argumentos: la función que se usará para recibir los resultados de la llamada, y la función a la que se llamará si se ha producido algún error. con estas premisas, todo el código Javascript que necesitaremos escribir en el navegador será el siguiente:

<script language=”javascript” type=”text/javascript”>

<!--

function MostrarHora() { PageMethods.DameHora(finLlamada, gestorErrores);

}

function finLlamada(resultado) { $get(“divHora”).innerHTML = resultado;

}

function gestorErrores(excepcion) {

$get(“divHora”).innerHTML = “Error en la llamada: “ + excepcion.get_message();

}

// -->

</script>

recuerda que la función MostrarHora es la que definimos para ser llamada cuando se pulse en el botón. La función $get() es una extensión global al lenguaje Javascript de las muchas que define asP.NeT aJaX y que nos permite acelerar la escritura de código. en este caso $get es equivalente a llamar al método estándar del DoM, document. getElementById, es decir, devuelve una referencia al elemento hTML cuyo nombre le pasemos como parámetro. en el ejemplo nos devuelve una referencia a la capa divHora de la página. con su propiedad innerHTML podemos introducir el hTML que necesitemos en su interior, en este caso la hora o el mensaje de error según lo que ocurra. ejecuta la nueva página y pulsa el botón de actualizar la hora del servidor. verás como de inmediato se muestra dentro de la capa en color rojo y funciona tan bien como la versión anterior. en apariencia no hemos ganado gran cosa puesto que todo parece ir igual de bien que en el ejemplo precedente. como antes, vamos a analizar las peticiones al servidor

66

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

para ver qué información estamos intercambiando. si capturamos con Fiddler la petición generada por el método de página veremos el resultado de la figura 4.

el método de página veremos el resultado de la figura 4. Figura 4.- contenidos de la

Figura 4.- contenidos de la llamada al servidor con un método de página

¡ahora sí que hemos optimizado el trabajo! La petición inicial ocupa 0 bytes, o sea va vacía porque no hay dato alguno que enviar. La respuesta nos devuelve en este caso el resultado de ejecutar el método en el servidor, codificado en formato JsoN, listo para ser usado desde Javascript. su tamaño: 16 bytes. Y eso porque hay 8 bytes extra que se añaden a todas las respuestas debido a la definición del objeto JsoN devuelto. si el resultado fuera un dato más largo seguirían siendo sólo 8 bytes más y su importancia relativa sería menor aún. es decir, hemos afinado al máximo el trasiego de información entre cliente y servidor, así como el código que ha de ejecutarse en el servidor, ya que no hay sobrecarga alguna por la ejecución de la página. Las ganancias de tamaño y rendimiento son mucho más espectaculares aún en páginas más grandes (reales) con más controles. si vemos el código fuente de la página generada podremos analizar con detalle el código Javascript autogenerado por el ScriptManager para conseguir toda esta funcionalidad. en la figura 5 se puede ver un fragmento del mismo.

A s P. net AJAX en el navegador

67

A s P. net AJAX en el navegador 67 Figura 5.- código autogenerado para habilitar los

Figura 5.- código autogenerado para habilitar los métodos de página

es evidente que para ciertos casos esta técnica ofrece grandes ventajas.

2.- llAMAdAS A SErvicioS WEb

La técnica anterior está bien para trabajar dentro del ámbito de una misma página, pero presenta algunas limitaciones. La más importante de ellas es que nos dificulta la reutilización del código, ya que los métodos están atados a una página concreta. si necesitamos utilizarlo en más de una página del sitio nos veremos obligados a definir otros tantos métodos estáticos de página. otra limitación es que si usamos Master Pages en nuestro desarrollo y éstas son las que contienen el ScriptManager tendremos que habilitar la propiedad EnablePa- geMethods en éste, sea necesario o no para cada una de las páginas. ello provocará que se genere código Javascript para llamar a métodos de página que es innecesario en muchas de nuestras asPX, ya que no los utilizarán. Una evolución mejorada de lo anterior es la capacidad del ScriptManager para habilitar las llamadas a servicios Web desde Javascript. ello nos permite tener en una única ubicación común todo el código reutilizable que vamos a llamar desde el navegador, eliminando la primera de las limitaciones anteriores. además se puede habilitar selectivamente el acceso a estos servicios desde el control ScriptMana- gerProxy, por lo que sólo generaremos código Javascript extra en las páginas que realmente lo necesiten.

68

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

 

Nota:

Por supuesto sólo podremos hacer llamadas a servicios Web que se encuentren ubicados en

el

mismo dominio que nuestras páginas. esto no es una limitación de asP.NeT aJaX sino

una característica de seguridad de todos los navegadores del mercado. si no existieran esta

otras limitaciones similares (como la que restringe el acceso sólo a las cookies de nuestro mismo dominio), nuestra privacidad y seguridad como usuarios de Internet se verían seria- mente amenazadas.

y

2.1.- definición de un servicio Web ASMX para ser llamado desde JavaScript

vamos a aprender a utilizar los servicios web desde Javascript mediante el desarrollo de un ejemplo práctico.

 

Nota:

No voy a explicar aquí los fundamentos de los servicios Web y su creación, ya que es algo que se sale del ámbito de este capítulo. se supone que si estás leyendo este libro deberías saberlo ya. si no es así te recomiendo mi libro de fundamentos de asP.NeT donde viene explicado. También podemos usar del mismo modo servicios creados con WcF (Windows Communica- tion Foundation), algo que haremos en otros ejemplos.

crearemos un pequeño proyecto que nos permita calcular la longitud de cual- quier cadena con un método en un servicio Web, llamando a éste desde Javascript. obviamente hacer esto en el servidor es un sinsentido y es sencillísimo hacerlo directamente con Javascript, pero lo utilizaremos únicamente para ilustrar los con- ceptos necesarios para consumir servicios Web desde el lado cliente. agrega al proyecto un nuevo servicio Web llamado “contador.asmx”. elimina el método de ejemplo que trae y crea uno nuevo llamado ContarPalabras, cuyo objetivo será el de devolver el número de palabras contenidas en la cadena que se le pase como parámetro. el código es extremadamente sencillo pues sólo nos interesa centrarnos en cómo llamarlo desde Javascript, pero podría ser todo lo complicado que quisiésemos, con llamadas a bases de datos o lo que fuera necesario. en la figura 6 se puede ver el resultado.

A s P. net AJAX en el navegador

69

A s P. net AJAX en el navegador 69 Figura 6.- El código de nuestro servicio

Figura 6.- El código de nuestro servicio Web de ejemplo

Tal y como está ahora mismo se trata de un servicio Web normal y corriente que acepta peticiones hTTP y devuelve sus resultados con XML. Por lo tanto sería factible realizar llamadas al mismo desde Javascript usando el objeto XMLhttpre- quest y procesando en el navegador el XML devuelto para operar con él. De hecho, como hemos visto en el capítulo de fundamentos, esta es la esencia original de aJaX (Asynchronous JavaScript And XML). sin embargo también hemos visto que existen formas mejores de utilizar este tipo de recursos remotos. en concreto utilizando JsoN (JavaScript Object Notation) para devolver los resultados. Y además sería fantástico si de alguna manera no tuviésemos que escribir a mano todo el código necesario para realizar la llamada y procesar los resultados ya que, como hemos estudiado, es algo engorroso y propenso a ciertos errores y situaciones problemáticas. si te fijas en la parte de arriba del código en la figura anterior verás que está comentado un atributo de la clase que representa al servicio Web. este atributo se llama ScriptService. su propósito es habilitar la generación automática de código Javascript especializado en el manejo del servicio con el que se decore. este código autogenerado permitirá realizar las llamadas a los métodos del servicio directamente desde el navegador sin tener que preocuparnos de los detalles de bajo nivel. esta “magia” se consigue gracias a un nuevo manejador para archivos .asmx que viene definido en asP.NeT aJaX y que sustituye al manejador habitual. si abrimos

70

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

el web.config de nuestra aplicación y buscamos en el XML veremos que tenemos unos nodos como los siguientes:

<httpHandlers> <remove verb=”*” path=”*.asmx”/> <add verb=”*” path=”*.asmx” validate=”false” type=”System.Web. Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35”/> </httpHandlers>

seguramente tendrá algunas entradas <add> más, pero nos quedamos con esta que es la que nos interesa. Lo que hace esta sección de la configuración es eliminar el manejador de servicios Web por defecto (nodo <remove>) y añadir uno nuevo especializado, ScriptHandlerFactory, que sabe interpretar este nuevo atributo que estamos estudiando y generar los formatos adecuados. No es necesario que toques nunca estos elementos. simplemente quería llamar tu atención sobre ellos para que sepas cómo funciona esto por debajo. Para seguir con el ejemplo, descomenta el atributo ScriptService en el código del servicio para que pueda funcionar en modo Javascript. Lanza la aplicación y navega hasta el servicio. si escribimos el sufijo /js a continuación del nombre del .asmx, se generará au- tomáticamente el código Javascript necesario para llamarlo y podremos descargarlo a disco para su examen. La figura 7 muestra cómo hacerlo:

a disco para su examen. La figura 7 muestra cómo hacerlo: Figura 7.- generación automática de

Figura 7.- generación automática de un proxy JavaScript para el servicio.

A s P. net AJAX en el navegador

71

este será el Javascript que usaremos de manera transparente en nuestra página para llamar al servicio cuando acabemos con el ejemplo. es útil saber que podemos obtenerlo así, ya que nos permitirá examinarlo y aprender sobre su modo de trabajar. De hecho existe la opción de obtener una versión de depuración del mismo, mucho más apropiada para su análisis ya que contiene comentarios y el código está orde- nado, si en lugar de /js utilizamos el sufijo /jsdebug. en la figura siguiente se puede ver un fragmento de los contenidos de este código que como vemos incluso lleva comentarios XML para generar documentación y obtener ayuda Intellisense desde el entorno de visual studio.

ayuda Intellisense desde el entorno de visual studio. Figura 8.- código JavaScript de la clase proxy

Figura 8.- código JavaScript de la clase proxy para acceso al servicio

este código hace uso de clases especializadas de la parte cliente de asP.NeT aJaX, como por ejemplo Sys.Net.WebServiceProxy, que encapsulan toda la funcio- nalidad necesaria. su análisis va mucho más allá del ámbito de este libro pero te resultará fácil seguirlo si tienes buenos conocimientos de Javascript.

2.2.- creación de la página cliente para llamar al servicio

recapitulemos lo que hemos hecho hasta ahora, que es bien sencillo: hemos creado un servicio Web y lo hemos decorado con el atributo ScriptService para poder lla- marlo desde Javascript directamente. ahora sólo nos resta crear una página de ejemplo que haga llamadas a nuestro flamante servicio y que ilustre la parte cliente del proyecto. agrega una nueva página al proyecto, “Usarcontador.aspx”. arrastra a su su- perficie desde la barra de herramientas un ScriptManager y, desde el grupo de controles hTML, un control <input> de texto, un <input> de tipo botón y un <div> para contener el resultado de contar las palabras con el servicio web. como vemos,

72

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

al igual que antes, no hemos utilizado ningún control de servidor a excepción del ScriptManager y todo el código que crearemos será de lado cliente.

y todo el código que crearemos será de lado cliente. Figura 9.- Nuestro ejemplo de uso

Figura 9.- Nuestro ejemplo de uso del servicio Web

Lo único que tenemos que hacer para poder utilizar el servicio desde el Javascript de nuestra página es registrarlo en el ScriptManager. Para ello utilizaremos una colección especial de este control llamada Services, y que hasta ahora no habíamos visto. su misión es indicar al ScriptManager nuestra intención de utilizar uno o más servicios Web desde el navegador, consiguiendo que se genere automáticamente el código necesario para ello al renderizar la página. si seleccionamos el control y vamos a sus propiedades veremos que hay un editor para esta colección, en el que podemos añadir referencias a servicios visualmente.

el que podemos añadir referencias a servicios visualmente. Figura 10.- El editor visual de referencias de

Figura 10.- El editor visual de referencias de Scripts

Los elementos introducidos en este editor se reflejan como entradas dentro de un nodo <Scripts> en el código hTML de la página. De hecho, los programadores

A s P. net AJAX en el navegador

73

experimentados, dado que todo el código que van a escribir es de lado cliente, normalmente editan directamente este nodo en la vista hTML de la página, sin usar el diálogo visual anterior. visual studio nos ofrece soporte Intellisense para hacerlo (figura 11), por lo que es incluso más rápido.

hacerlo (figura 11), por lo que es incluso más rápido. Figura 11.- Establecimiento manual de referencias

Figura 11.- Establecimiento manual de referencias a servicios

esta colección está disponible también en el control ScriptManagerProxy, por lo que podemos usarlas en entornos con Master Pages. a partir del momento en que hemos registrado el servicio, visual studio nos ofrece soporte Intellisense para su uso desde Javascript (figura 12), obteniendo ayuda a medida que escribimos sobre sus métodos y propiedades (1) y sobre los diferentes parámetros de los mismos (2). esto nos facilita sobremanera el trabajo con este sistema.

esto nos facilita sobremanera el trabajo con este sistema. Figura 12.- Soporte intellisense para el uso

Figura 12.- Soporte intellisense para el uso de los servicios con JavaScript

74

tecnologías A s P. net 4.0 (saltando desde la versión 2.0)

el código necesario para usar el servicio es directo y sencillo. accedemos al mismo a partir del nombre de la clase y el nombre de sus métodos, exactamente igual a cómo haríamos desde código de servidor. como parámetros se le pasaran los mismos que el método original en el servicio Web y, a mayores, una referencia a la función para procesar los resultados y otra a la función para gestionar los posibles errores. exactamente igual que hemos visto en para los métodos de pagina. el último parámetro posible (userContext, como se ve en la figura 12) es opcional y sirve para pasar información específica de la llamada de forma que podamos distinguir unas de otras si hacemos varias llamadas seguidas al servicio, o si usamos los mismo manejadores de éxito y fracaso para varios servicios diferentes. Nuestro código final es tan sencillo como este:

<script type=”text/javascript” language=”javascript”>

<!--

function LlamarServicioContador() {

Contador.ContarPalabras($get(“txtFrase”).value, finLlamada, gestorErrores);

}

function finLlamada(resultado) { $get(“divRes”).innerHTML = resultado;

}

function gestorErrores(excepcion) {

$get(“divRes”).innerHTML = “Error en la llamada: “ + excepcion.get_message();

}

//-->

</script>

como vemos prácticamente idéntico al que vimos cuando trabajábamos con métodos de página. ahora ya podemos ejecutar la aplicación. Introduciremos una frase en el campo de texto y al pulsar el botón veremos como de inmediato y sin refrescar la página obtenemos el resultado correcto en el div habilitado a tal efecto.

el resultado correcto en el div habilitado a tal efecto. Figura 13.- Nuestro ejemplo en funcionamiento

Figura 13.- Nuestro ejemplo en funcionamiento

el usuario no notará en absoluto que se ha ido al servidor a realizar la tarea. el trasiego de información entre cliente y servidor es mínimo, ya que sólo se envía y se recibe información codificada como JsoN (Figura 14). además tenemos toda la funcionalidad concentrada en un solo punto y accesible para toda la aplica-

A s P. net AJAX en el navegador

75

ción. al tratarse de un servicio Web podremos sacarle partido a características de éstos como, por ejemplo, la caché de datos para mejorar el rendimiento.

por ejemplo, la caché de datos para mejorar el rendimiento. Figura 14.- Análisis de la petición

Figura 14.- Análisis de la petición realizada al servicio web

el uso de servicios Web y servicios WcF diseñados para comunicación desde Javascript en el cliente es realmente útil. Los podemos utilizar para intercambiar entre cliente y servidor todo tipo de datos complejos y no sólo simples cadenas y números, como hemos visto en los ejemplos. Desde el cliente además se pueden enviar datos al servidor (por ejemplo un registro de la base de datos para actualizar) y no sólo limitarnos a recibir información. De hecho las principales novedades de asP.NeT 4.0 en lo que respecta a aJaX tienen que ver con llevar cada vez más parte del procesamiento al lado del cliente y aprovechar la capacidad de llamar a servicios Web para generar las interfaces de datos puramente en Javascript. en el siguiente capítulo profundizaremos en todo ello.

3.- SErvicioS dE APlicAcióN: MEMbErShiP y rolES dESdE El NAvEgAdor

Uno de los servicios más útiles de asP.NeT es el de seguridad, encarnado en las clases Membership