Cutting Edge
Arquitectura de aplicaciones AJAX, segunda parte
Dino Esposito
Descarga de código disponible en:
CuttingEdge2007_10.exe
(151 KB)
Browse the Code Online

Contenido
Al usar las extensiones AJAX de ASP.NET para llevar a cabo la transición de un sitio web hacia una experiencia AJAX, hay dos modelos principales de programación entre los que se puede elegir: la representación parcial y los servicios de script. En la columna del mes pasado hablé de la representación parcial desde una perspectiva principalmente arquitectónica. En resumen, con la representación parcial, no es necesario cambiar la arquitectura subyacente de una aplicación ASP.NET; es decir, es una manera fácil de llevar a cabo la implementación de algunos de los mejores elementos de que dispone AJAX, tales como las actualizaciones sin parpadeos para páginas web. Esta mejora en el comportamiento se consigue simplemente al agregar algunos nuevos controles de servidor (concretamente, ScriptManager y UpdatePanel) y hacer que éstos realicen algunas tareas en modo silencioso para transformar una devolución tradicional en una solicitud asincrónica ejecutada a través del objeto XMLHttpRequest. Este método es bastante fácil de usar ya que aplica simplemente la funcionalidad de AJAX al modelo existente de desarrollo web.
Si está preparado para un cambio de paradigma total en lo que respecta a la creación de aplicaciones AJAX, tendría que estar considerando el método de servicios de script. Después de todo, la típica arquitectura de AJAX es bastante fácil de entender. La figura 1 muestra una vista de alto nivel de su funcionamiento. Hay un back-end compuesto de servicios específicos de la aplicación, que son generalmente sólo una fachada de AJAX invocable por script que se encuentra encima del nivel intermedio del sistema donde reside y funciona la lógica empresarial. Los servicios y el cliente front-end se intercambian datos mediante HTTP usando una variedad de formatos para pasar parámetros y devolver valores. Tras haber recibido y procesado los datos, el cliente front-end, que está compuesto de código JavaScript ejecutado en el cliente, se enfrenta a la tarea no trivial de crear una interfaz gráfica de usuario con HTML y JavaScript. La dependencia de JavaScript es una restricción estructural del explorador y no cambiará si antes éste no admite capacidades de programación más eficaces.
Figura 1 La arquitectura típica de AJAX
Inicio de sesión con AJAX
Apartarse del modelo clásico de ASP.NET tiene muchas repercusiones prácticas. Considere el proceso de inicio de sesión y vea cómo cambiaría en una solución AJAX absoluta.
Actualmente con ASP.NET, habilitar el proceso de inicio de sesión consiste en configurar la página de inicio con el control Login, configurar las páginas protegidas con el control LoginView y configurar el proveedor de suscripciones de ASP.NET. Las páginas protegidas usarán o bien el inicio de sesión o bien plantillas anónimas para reflejar gráficamente el resultado del proceso de autenticación. En ASP.NET 2.0, es posible llevar a cabo la mayor parte de este trabajo sin necesidad de escribir ningún código. Sin embargo, para iniciar sesión correctamente, se produce una redirección (HTTP 302) cuando el usuario llega a una página protegida, una devolución desde la página de inicio de sesión para autenticar las credenciales y, a continuación, otra redirección de vuelta a la página solicitada al principio.
Esto no tiene por qué ser necesariamente así con las páginas de AJAX. Si el usuario solicita una página protegida de la barra de direcciones, no se puede hacer mucho sino repetir la experiencia de ASP.NET. Sin embargo, si la página contiene vínculos que llevan a páginas protegidas, se puede agregar algún script al evento de clic del vínculo para comprobar si el usuario está autenticado. Si no es así, puede generar un cuadro de alerta para advertir al usuario, tal como se muestra a continuación:
function checkFirst()
{
var loggedIn = Sys.Services.AuthenticationService.get_isLoggedIn();
if (!loggedIn)
{
alert("You must be logged in to follow this link");
return false;
}
return true;
}
Como puede ver, este método usa un marco de cliente que, entre otras cosas, permite comprobar si el usuario actual inició sesión. Con las extensiones AJAX de ASP.NET, esto se consigue a través de la clase Sys.Services.AuthenticationService.
Este mismo servicio puede usarse para autenticar un usuario una vez que haya especificado sus credenciales correctas. En este caso, no se da ninguna redirección ni devolución. Todo tiene lugar en el contexto de la misma página, tal como muestra el fragmento de código siguiente:
function OnLogin()
{
Sys.Services.AuthenticationService.login(
$get("UserName").value,
$get("Password").value,
false,
null,
null,
OnLoginCompleted,
OnLoginFailed);
}
Comprobar credenciales pasa a ser una operación de script estándar que hace uso de un servicio de script para realizar la autenticación. El desarrollador puede decidir si desea actualizar la interfaz de usuario de la página del cliente para reflejar que el usuario inició sesión tras haberse realizado la autenticación correctamente. Salvo que el marco usado proporcione un modelo de objeto para ajustar el protocolo HTML en controles, tendrá que tomar la ruta más larga del scripting de Modelo de objetos de documento (DOM). Observe que estas extensiones AJAX de ASP.NET no ofrecen actualmente un modelo de objetos para representar fragmentos de marcado como controles.
Versiones de servicios
En AJAX, un servicio indica un fragmento de código que reside en el dominio de la aplicación y expone funcionalidad al código del script del cliente. Un servicio usado en AJAX requiere un diseño para crear una implementación que proteja el back-end de la aplicación real y el nivel intermedio contra una interacción directa con el usuario. ¿Es éste servicio un servicio web WS-*? ¿Es posible que se trate de un servicio de arquitectura orientada a servicios (SOA)?
El servicio ideal para las aplicaciones AJAX tiene que ver principalmente en la exposición de datos y recursos para los clientes web. Se puede tener acceso a él a través del protocolo HTTP y requiere que los clientes usen direcciones URL (y, opcionalmente, encabezados HTTP) para tener acceso a los datos y las operaciones de comando. Los clientes interactúan con el servicio mediante verbos HTTP como, por ejemplo, GET, POST, PUT y DELETE. Es decir, la dirección URL representa un recurso y el verbo HTTP describe la acción que desea que lleve a cabo el recurso. Los datos intercambiados en estas interacciones se representan mediante formatos sencillos, tales como JSON y XML simple, o mediante formatos de distribución como, por ejemplo, RSS y ATOM.
Un servicio con estas características es un servicio de Transferencia de estado de representación (REST). Para obtener más información acerca de la definición de REST, lea el documento original que describe la perspectiva que se esconde detrás de REST (disponible en ics.uci.edu/~fielding/pubs/dissertation/top.htm).
Al final, los servicios que las aplicaciones AJAX usan tienden a no usar SOAP para comunicarse y no son necesariamente servicios autónomos en el sentido de SOA. En cambio, están enlazados a la plataforma y al dominio en los que se hospedan. Según esto, es difícil que se puedan denominar servicios web WS-* o servicios SOA.
Además, estos servicios se encargan de no tener documentación pública ni un esquema de detección, a diferencia de, por ejemplo, el Lenguaje de descripción de servicios web (WSDL) para los servicios web WS-*. Esto reduce el número de dependencias del servicio y permite un desarrollo más rápido del código del servicio. Después de todo, el paradigma recomendado para los servicios AJAX es menos ambicioso que el paradigma que hay detrás de los servicios web y SOA, pero sigue siendo eficaz para el contexto en el que se pretende usar.
Observe que durante el resto de la columna, voy a usar la expresión "servicios AJAX" para referirme a los servicios que se usan para implementar el back-end de una aplicación AJAX mediante el método de servicios de script.
¿Qué devuelven los servicios AJAX?
Puesto que los servicios AJAX se exponen exclusivamente mediante HTTP, es posible usar virtualmente cualquier formato de texto para empaquetar el cuerpo de solicitudes y respuestas. JavaScript Object Notation (JSON) es el formato que se usa con mayor frecuencia, aunque otros, tal como XML simple y el texto sin formato, también pueden usarse.
JSON es un formato basado en texto diseñado para trasladar el estado de un objeto a través de los niveles de una aplicación. Para un objeto JavaScript, una cadena JSON puede analizarse fácilmente a través de la conocida función eval. El formato JSON describe el objeto, tal como se muestra a continuación:
{"ID":"ALFKI", "Company":"Alfred Futterkiste"}
La cadena indica un objeto con dos propiedades, la propiedad ID y la propiedad Company, y sus respectivos valores de texto serializado. Si a una propiedad se le asigna un valor no primitivo como, por ejemplo, un objeto personalizado, el valor se serializa de forma recursiva en JSON, tal como se muestra a continuación:
"ID":"ALFKI",
"Company":"Alfreds Futterkiste",
"Location":
"{"City":"Berlin", "Country":"Germany"}",
}
Cuando se procesa con la función eval, las cadenas JSON pasan a ser una matriz asociativa, una especie de recopilación de nombres o valores, donde cada entrada contiene un nombre y un valor. Si la cadena JSON está destinada a representar el estado de un objeto personalizado, por ejemplo, Customer, el usuario debe asegurarse de que la definición de la clase correspondiente esté disponible en el cliente. Es decir, la función eval de JavaScript extrae información por sí misma de la cadena JSON a un contenedor genérico. Si necesita que esta información se exponga como un objeto personalizado, por ejemplo, el objeto Customer, la tarea de suministrar la definición de la clase y de cargar los datos depende totalmente del usuario o del marco que use. Para obtener más información acerca de la sintaxis y de los objetivos de JSON, consulte
www.json.org.
JSON frente a XML
Durante años, XML ha sido el lenguaje recomendado como lengua franca para web. Ahora que AJAX está cambiando la Web tal y como la conocemos, XML está siendo arrinconado a favor de JSON en lo que se refiere a la representación de datos.
JSON es ligeramente más sencillo y más adecuado si se usa con el lenguaje de JavaScript. Aunque se puede discutir cuál es el más fácil de entender para nosotros, los humanos, para un explorador web, JSON es ciertamente más fácil de procesar que XML. Con JSON, no se necesita nada parecido al analizador XML. Todo lo que se necesita para analizar el texto es crear correctamente el lenguaje JavaScript. Dado que JSON es bastante menos ambicioso que XML, es también menos detallado. Esto no quiere decir que JSON es perfecto; la gran cantidad de comas y comillas que JSON requiere hace que sea un formato bastante estrambótico.
Con JSON también se obtiene una ventaja arquitectónica clave a un costo relativamente bajo. Se razona en términos de objetos en todo momento. En el servidor, se definen las entidades y se implementan como clases en su lenguaje administrado favorito. Cuando un método de servicio necesita devolver una instancia de alguna clase, el estado del objeto se serializa para JSON y viaja por la red. En el cliente, la cadena JSON se recibe y se procesa, y su contenido se carga en una matriz o una clase de objeto JavaScript de reflejo que tiene la misma interfaz que la clase del servidor. La interfaz de esta clase se infiere de la secuencia de JSON. De este modo, el servicio y el código de página del cliente usan la misma definición lógica de una entidad.
Desde un punto de vista puramente técnico, los servicios AJAX no requieren estrictamente la implementación de JSON como el formato de representación de datos. De hecho, podría lograrse el mismo resultado con XML, pero entonces se necesitaría un analizador XML que se pudiera usar desde JavaScript. Es posible que el análisis de texto XML sencillo en JavaScript no suponga ningún problema, pero usar un analizador a gran escala es otra historia. Los aspectos relacionados con el rendimiento y la funcionalidad probablemente llevarán a la existencia de numerosos componentes aparentemente semejantes pero que tienen poco en común. Y entonces surge la pregunta de si el analizador XML de JavaScript será compatible con elementos como los espacios de nombres, los esquemas, los espacios blancos, los comentarios, las instrucciones de procesamiento, etc.
En mi opinión, en pos de la compatibilidad acabaría teniendo un subconjunto de XML limitado a nodos y atributos. Llegados a ese punto, es meramente cuestión de elegir entre los corchetes angulares de XML o las llaves de JSON.
Temas de seguridad
AJAX permite una experiencia de exploración más dinámica e interactiva. Sin embargo, esto aumenta el área de la superficie para los tipos de ataques habituales como, por ejemplo, el scripting entre sitios (XSS) y la suplantación de solicitudes entre sitios (CSRF). Estos tipos de ataques los causan un atacante que inserta código script en una página web, generalmente a través de una dirección URL, y de este modo el atacante puede controlar el explorador web mediante acciones como, por ejemplo, robar nombres de usuario y contraseñas o ejecutar solicitudes HTTP sin que el usuario lo sepa.
Un atacante puede, por ejemplo, insertar script malintencionado en el cliente mediante una etiqueta de <script> creada dinámicamente, lo que permite que los datos se importen al sitio web del atacante. En el caso de un ataque CSRF, el atacante puede insertar un script en el cliente y de este modo permitirle ejecutar métodos de servicios no autorizados en otro sitio web usando información de autenticación guardada (como, por ejemplo, las cookies) en el cliente.
JSON es una forma eficaz de empaquetar datos y suministrarlos al cliente. Sin embargo, dado que JSON se considera un subconjunto seguro del lenguaje JavaScript (excluye las operaciones de asignación y de invocación), muchas aplicaciones AJAX pasan simplemente cadenas JSON directamente a la función eval de JavaScript para crear objetos JavaScript. Como resultado, una cadena JSON formada incorrectamente proporciona un nuevo medio para que un atacante pueda ejecutar un script no autorizado en el cliente.
La mayoría de estos tipos de ataques dependen de la explotación del verbo GET en una solicitud HTTP. Afortunadamente, los servicios AJAX de ASP.NET tienen el verbo GET deshabilitado de forma predeterminada en los servicios remotos. Además, se puede requerir que se establezca un tipo de contenido especial en la solicitud: en cualquier otro caso, un servicio AJAX de ASP.NET rechazará la llamada. Según su diseño, cualquier llamada directa realizada desde una etiqueta <script> a un servicio AJAX de ASP.NET tiene un tipo de contenido incorrecto y genera un error.
Los servicios en AJAX de ASP.NET
Con las extensiones AJAX de ASP.NET es posible implementar servicios de script de dos maneras: mediante un tipo especial de servicios web de ASP.NET o bien a través de métodos de página. En el primer caso, sólo se lleva a cabo el diseño y la creación de una clase vinculada a un recurso ASMX:
<%@ WebService Language="C#"
CodeBehind="~/App_Code/TimeService.cs"
Class="IntroAjax.WebServices.TimeService" %>
Esta clase puede heredarse opcionalmente de la clase WebService y debe contener el nuevo atributo ScriptService:
[ScriptService]
public class TimeService : System.Web.Services.WebService
{
...
}
Cada método que es invocable por script se declara público y se marca con el atributo habitual WebMethod.
Los métodos de página son simplemente métodos públicos y estáticos, todos marcados como WebMethod, que se definen en el contexto de una única página ASP.NET. Sólo pueden invocarse desde dentro de la página de host. Aparte de las diferencias de almacenamiento, el entorno de AJAX de ASP.NET procesa una llamada a un servicio web o método de página de la misma manera.
Debe entender que los servicios AJAX representan una parte del back-end. No se trata de servicios web públicos en el sentido de un servicio web WS-*, los cuales están totalmente documentados por un script WSDL y a los cuales se tiene acceso a través de los comandos POST que contienen datos SOAP. En realidad, los servicios AJAX son servicios locales y, en general, se definen en la misma aplicación que los llama. Sin embargo, también pueden encontrarse en una aplicación web o incluso en un sitio web diferentes, siempre y cuando residan en el mismo dominio.
El atributo ScriptService desempeña un papel fundamental al habilitar el tiempo de ejecución de AJAX de ASP.NET para aceptar las llamadas al servicio. Sin el atributo ScriptService, se genera una excepción en el servidor cuando se intentan realizar las llamadas. La figura 2 muestra el mensaje que se devuelve cuando una página AJAX se vincula a un servicio no marcado con este atributo. Tenga en cuenta que la página de la figura nunca se muestra a un usuario. Cuando se conecta a una página AJAX de ASP.NET que declara usar este servicio, se reciben todo los elementos marcados. El marcado devuelve un código de error HTTP 500 porque la maquinaria interna de ASP.NET se niega a procesar las llamadas de script dirigidas a los servicios web de ASP.NET que carecen de este atributo.
Figura 2 Referencias de páginas a servicios que no pueden usarse con script (Hacer clic en la imagen para ampliarla)
De forma predeterminada, los métodos de servicio AJAX se invocan únicamente mediante el verbo POST y devuelven datos con el formato JSON. Sin embargo, es posible cambiar esta configuración mediante el atributo opcional ScriptMethod en métodos de servicios individuales. La figura 3 detalla los parámetros que admite el atributo ScriptMethod. Los datos devueltos al cliente pueden cambiarse a XML e incluso se puede agregar compatibilidad para las solicitudes GET. Pero como ya mencioné antes, este cambio aparentemente inocente puede abrir nuevas posibilidades para atacantes y exponer la posibilidad de realizar llamadas entre sitios al método. El fragmento de código siguiente muestra la definición de un método de servicio web:

Figure 3 Parámetros del atributo ScriptMethod
| Parámetro |
Descripción |
| ResponseFormat |
Especifica si la respuesta será serializada como JSON o como XML. El parámetro predeterminado es JSON, pero el formato XML puede ser útil cuando el valor del método que se devuelve es XmlDocument. |
| UseHttpGet |
Indica si un verbo GET de HTTP puede usarse para invocar al método de servicio web. Por motivos de seguridad, se establece en falso de forma predeterminada. |
| XmlSerializeString |
Indica si todos los tipos de devolución, incluidas las cadenas, se serializan como XML. El valor predeterminado es falso. El valor de la propiedad se pasa por alto cuando el formato de la respuesta se establece en JSON. |
[WebMethod]
[ScriptMethod]
public DateTime GetTime()
{
...
}
Si no va a cambiar ninguna configuración predeterminada (que es lo que recomiendo en la mayoría de los casos), entonces se puede omitir el atributo ScriptMethod. Sin embargo, el atributo WebMethod es obligatorio.
Servicios AJAX de ASP.NET y SOAP
Una vez creado, un servicio web AJAX se publica como un recurso ASMX. De forma predeterminada, se trata de una dirección URL pública y los clientes AJAX lo pueden consumir. También los clientes y las herramientas SOAP puede detectarlo y consumirlo. No obstante, se puede optar por deshabilitar a estos clientes y herramientas SOAP. Simplemente especifique la configuración siguiente en el archivo web.config de la aplicación ASP.NET que hospeda el servicio:
<webServices>
<protocols>
<clear />
</protocols>
</webServices>
Esta configuración sencilla deshabilita cualquier protocolo definido para los servicios web ASP.NET 2.0 (en concreto, SOAP) y permite que el servicio sólo responda a las solicitudes JSON. Tenga en cuenta que con esta configuración, ya no se puede llamar al servicio web a través de la barra de direcciones del explorador para realizar una prueba rápida. Igualmente, tampoco es posible pedir que WSDL agregue el sufijo ?wsdl a la dirección URL.
Para habilitar AJAX de ASP.NET en una aplicación web, debe incluir la configuración siguiente en el archivo web.config:
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false"
type="System.Web.Script.ScriptHandlerFactory, System.Web.Extensions" />
</httpHandlers>
El nodo <remove> descarta el controlador HTTP predeterminado para los recursos ASMX, el que administra las solicitudes a través de SOAP. El nodo <add> agrega un controlador HTTP nuevo que comprueba básicamente el tipo de contenido de cada solicitud ASMX entrante y la atiende mediante JSON si el encabezado del tipo de contenido está establecido en application/json. Si no es así, el controlador HTTP supone que la solicitud se basa en SOAP y la reenvía al controlador de servicio web estándar ASP.NET 2.0. Si el protocolo SOAP se encuentra deshabilitado, se rechazará la solicitud.
Al final, y a pesar de las apariencias, un servicio AJAX de ASP.NET no necesariamente implica el uso de SOAP. Pero se garantiza la compatibilidad para clientes SOAP, salvo si se encuentra deshabilitado de forma explícita en el archivo web.config.
Para que un servicio AJAX de ASP.NET funcione según lo previsto, la solicitud entrante debe tener el encabezado HTTP del tipo de contenido establecido en application/json. Esto es también un remedio excelente contra los ataques entre sitios realizados a través de la etiqueta <script>.
Invocación de los servicios AJAX
Para invocar un servicio AJAX, un cliente AJAX sigue el mismo patrón que se usa para establecer referencias con los servicios web en Windows y aplicaciones tradicionales de ASP.NET. Una clase proxy ofrece la misma interfaz local que el servicio remoto. En aplicaciones AJAX de ASP.NET, este proxy es una clase de JavaScript que el tiempo de ejecución genera cuando la página se descarga.
La clase proxy de JavaScript tiene el mismo nombre que el servicio de script y varias propiedades adicionales. Incluye el mismo conjunto de métodos, aunque con una firma ligeramente ampliada. En general, no hay necesidad de consultar el código fuente de la clase proxy. Pero si desea ver su estructura, intente invocar la dirección URL siguiente desde la barra de direcciones del explorador:
http://.../service.asmx/js
El explorador descargará un archivo JavaScript que puede guardar en el disco local para un examen posterior.
La clase proxy de JavaScript se hereda desde una clase base denominada Sys.Net.WebServiceProxy. Esta proporciona las capacidades básicas para realizar llamadas JSON. La descarga de código para esta columna ofrece una clase proxy para un servicio web con la interfaz siguiente:
interface ITimeService
{
DateTime GetTime();
string GetTimeFormat(string format);
}
La clase proxy de JavaScript representa las propiedades que se enumeran en la figura 4. Cada método reflejado tiene tres parámetros además de su conjunto normal de argumentos. Estos son la función de devolución de llamada que se debe llamar para comprobar si el método se realizó correctamente, la función de devolución de llamada que se debe llamar para comprobar si el método tuvo algún error o tiempos de espera y el objeto de contexto que se debe pasar a ambas devoluciones de llamada. Las tres propiedades relacionadas de forma predeterminada que se muestran en la figura 4 permiten volver a usar la misma función para varias llamadas, por ejemplo, una función de JavaScript exclusiva para administrar errores. A continuación se incluye código de ejemplo que invoca servicios AJAX remotos desde una página AJAX de ASP.NET:

Figure 4 Propiedades de la clase Proxy de JavaScript
| Propiedad |
Descripción |
| Path |
Indica la dirección URL del servicio web subyacente. |
| Timeout |
Indica durante cuántos milisegundos se permite la ejecución del método antes de llamar a un tiempo de espera. |
| defaultSucceededCallback |
Indica la función predeterminada de devolución de llamada de JavaScript para invocar una llamada correctamente. |
| defaultFailedCallback |
Indica la función predeterminada de la devolución de llamada de JavaScript, si la hay, para invocar una llamada realizada incorrectamente o de tiempo de espera. |
| defaultUserContext |
Indica el objeto predeterminado de JavaScript, si lo hay, para pasarlo a las devoluciones de llamada realizadas correcta e incorrectamente. |
function getTime()
{
IntroAjax.WebServices.TimeService.GetTimeFormat(
"ddd, dd MMMM yyyy [hh:mm:ss]", onMethodComplete);
}
function onMethodComplete(results)
{
$get("Label1").innerHTML = results;
}
Las devoluciones de llamada invocadas al final de una llamada del método (independientemente del resultado) tiene el prototipo siguiente:
function method(results, context, methodName)
El parámetro context representa el objeto de contexto que se especificó al realizar la llamada. El parámetro methodName es una cadena establecida en el nombre del método de servicio. Por último, para que una devolución de llamada invoque una llamada correctamente, el parámetro results es un objeto que contiene la versión de JavaScript del valor devuelto del método. En cambio, ante un error de la devolución de llamada, esto representa un objeto Sys.Net.WebServiceError.
Creación de la interfaz de usuario
AJAX trata todos los aspectos acerca de la experiencia de usuario en el sentido más amplio: sensación de continuidad, actualizaciones sin parpadeos, facilidades de interfaz, mashups, datos activos, entre otros. Pero sólo es posible usar el explorador y su conjunto de características de programabilidad: principalmente, el modelo de objetos del explorador, la implementación DOM, la compatibilidad para extensiones DHTML, CSS, JavaScript y complementos.
JavaScript es la principal herramienta que se usa para crear y manipular la interfaz de usuario. El patrón típico para las tareas de la interfaz de usuario supone que el cliente usa JavaScript para invocar los servicios remotos, recibe datos JSON o quizás XML y, a continuación, vuelve a disponer la página de forma que se muestren los cambios.
Un modelo tan sencillo no es necesariamente eficaz cuando se proyecta con el tamaño y la complejidad de una aplicación real. Volver a organizar la página para incorporar datos actualizados que siguen a una llamada remota plantea unos problemas nada triviales, ya que la estructura de la interfaz de usuario es cada vez más elaborada. Y, ¿dónde se encuentra el umbral en el que una interfaz de usuario elaborada se convierte en un problema?
Hay esencialmente tres características de interfaz de usuario de las que depende cada aplicación realista, especialmente las aplicaciones empresariales: el diseño, el enlace de datos y el estilo. El entorno de JavaScript no es compatible con ninguna de estas características, salvo por alguna compatibilidad de estilo mediante CSS. Además, JavaScript es un lenguaje interpretado donde, por ejemplo, la programación intensiva a menudo tiene como consecuencia problemas de memoria debido a errores sutiles del explorador y de una programación defectuosa.
Considere un escenario relativamente frecuente y simple, la paginación de una cuadrícula de datos, por ejemplo. Una cuadrícula es en última instancia una tabla bastante compleja que el explorador tiene que analizar y representar para cada solicitud. Es difícil para un usuario calcular el costo de esta operación de representación la primera vez que se sirve la página, ya que está incorporada en la descarga general de la página. Pero tras realizarse una solicitud de devolución de AJAX para una nueva página de cuadrícula, el costo de la actualización de la ventana del explorador se hace evidente de forma inmediata. El explorador recibe una cadena JSON que contiene una recopilación de objetos y debe convertir esa recopilación en una tabla nueva. Debe crearse en el cliente una cadena HTML de gran tamaño, redactando texto en algún búfer de la memoria. La misma cadena, si es correcta, tiene que representarse de forma gráfica.
Cuando se realizan estas operaciones intensivas, puede advertirse que el tiempo de respuesta no es nada idóneo. Ante escenarios como éste, se necesitan habilidades avanzadas de JavaScript y DHTML para dar con soluciones eficaces.
Un método alternativo es generar previamente parte del marcado en el servidor. De este modo, el servicio remoto no sólo devuelve datos sino que los incorpora también a la información de marcado. En el servidor, el marcado se crea a través de código compilado, puede depurarse y probarse más fácilmente y se puede tener acceso a herramientas de programación más eficaces con el fin de agregar características de accesibilidad. Por otro lado, viajan más datos viajan a través de la red (pero recuerde que la cantidad de datos es todavía mucho menor que con las devoluciones periódicas de ASP.NET).
Por último, sólo cabe decir que se necesitan herramientas más eficaces en el cliente para que la creación de interfaces de usuario realistas sea eficaz desde un punto de vista del rendimiento y del desarrollo. Las bibliotecas buenas y completas de widgets y controles son esenciales para cualquier desarrollador. Pero incluso las mejores y más optimizadas librerías pueden hacer poco para contrarrestar la limitación inherente de un lenguaje interpretado como es JavaScript. Quizás Silverlight, un complemento del explorador de plataforma cruzada de Microsoft que incorpora un subconjunto del marco de Windows ® Presentation Foundation (WPF), va a poder proporcionar algún día el entorno de cliente que los desarrolladores web desean para la siguiente generación de aplicaciones web y AJAX. Pero Silverlight es un complemento externo: requiere una descarga separada y todavía está en proceso de maduración. La versión 1.0 acaba de lanzarse al mercado, pero se necesitan características más elaboradas para poder usarla y crear un nivel de presentación de aplicaciones web del mundo real.
Lo que significa
La representación parcial es el método más fácil para usar con AJAX. En concreto, es muy conveniente para agregar capacidades AJAX a aplicaciones heredadas para las que no se dispone del tiempo, presupuesto o deseo para rediseñarlas. Desde un punto de vista arquitectónico, la representación parcial es una extensión inteligente para el ASP.NET de hoy que conserva el mismo modelo de aplicación y motor subyacente.
Una arquitectura AJAX absoluta se basa en un cliente y un servidor ligeramente vinculados, básicamente dos mundos separados y conectados a través de HTTP con mensajes de intercambio JSON. En una arquitectura AJAX absoluta, se dispone de un back-end basado en servicios y de un front-end equipado con JavaScript. La carga de crear una interfaz de usuario HTML eficaz depende completamente del usuario o de la biblioteca de controles que elija. Sin embargo, este desacoplamiento permitirá que tecnologías emergentes como, por ejemplo, Silverlight sigan permitiendo a los desarrolladores web crear interfaces de usuario más interactivas y sin limitaciones procedentes de la plataforma del servidor.
Envíe sus preguntas y comentarios a Dino a la dirección cutting@microsoft.com.
Dino Esposito es profesor en Solid Quality Learning y autor de Programming ASP.NET 3.5 Core Reference (Microsoft Press, 2007), que pronto estará disponible. Con residencia en Italia, Dino participa habitualmente en conferencias de eventos del sector en todo el mundo. Puede visitar su blog en
weblogs.asp.net/despos.