Script Callbacks en ASP.NET 2.0
Fecha: 31/Ene/2006 (30/01/2006)
|
ASP.NET 2.0 Script Call Backs
Durante los últimos meses ha esta sonando mucho el termino “AJAX” (ver mi articulo) el cual significa “Asynchronous Javascript And Xml”, esta técnica ha creado mucho debate sobre su reciente popularidad y la interrogante sobre quien tiene el crédito de haberlo inventado. Algunas personas mencionan que realmente fue Microsoft quien dio origen a lo que hoy es conocido como AJAX, para los que recuerdan en el año 1997 (Yo no !!!) con IE versión 4.0 se introduce por primera vez la capacidad de poder modificar dinámicamente el contenido de una pagina a través de DOM (Document Object Model) y por medio de scripts del lado del cliente. Luego por el año 1999 IE introduce el objeto XMLHttpRequest; es aquí donde comienzan a surgir aplicaciones que utilizan un proceso asincrónico para poder manipular información desde un navegador, sin tener que actualizar todo el contenido de la pagina; posteriormente web browsers como safari, opera y firefox incluyeron este feauture para los desarrolladores.
Lo genial del caso es que una persona, con visión empresarial a mi punto de vista, comenzó a popularizar el termino AJAX en febrero de 2005, esta persona es Jesse James (ver essay), como mencionan muchas personas él “monetarizo” el termino y a partir de este momento se crea el boom en la industria, muchas empresas comienzan a enfocarse a poder proveer herramientas o aplicaciones “AJAX enabled”, para enriquecer la interfaz de usuario. Inclusive hoy en día comienza sonar el futuro del Internet, estoy hablando de “WEB 2.0”.
Bueno pero el objetivo de este artículo no es AJAX, es “Script Callbacks”, se preguntaran que significa?. Bueno, comencé este articulo con una introducción de AJAX, para poder justificar el por que Microsoft en ASP.NET 2.0 incluye este nuevo feature; y precisamente el objetivo de los Script Callbacks es poder generar llamadas asincrónicas hacia el servidor sin la necesidad de tener que generar todo el contenido de una página. La buena noticia para nosotros, desarrolladores, es que este modelo ya esta incluido en esta tecnología y poderlo poner en funcionamiento es sencillo. Espero en los próximos párrafos poder brindarles una introducción básica hacia el tema y llevarlo a la práctica con una pequeña demostración.
En la figura 1 podemos ver la comparación entre el modelo original Postback versus
el modelo utilizando Callbacks, como podemos ver cuando utilizamos un postback la
información es enviada al servidor y como aparece en la figura se ejecutan los eventos
de la pagina como normalmente sucede. La respuesta es todo el contenido de la
página generado en el servidor. En contra parte, el modelo callback utiliza una
función del lado del cliente que es la encargada de enviar la información al servidor,
nuevamente los eventos de la pagina son procesados, pero la diferencia que existe es
que en este caso hay un event handler que invocará un evento que nosotros definimos
para procesar la información, luego que la solicitud es procesada la respuesta es solo
un valor simple con la información solicitada. Esto definitivamente mejora el tiempo
de respuesta por que cuando utilizamos postbacks siempre estamos enviando de
vuelta al cliente todo el contenido de la pagina, mientras que en un callback solo se
envía al cliente la información que él solicita.
Creando Una Pagina con Callbacks:
Los pasos necesarios para poder crear una pagina que utilice Callbacks son los siguientes:
- Implementar la interfase ICallBackEventHandler en la clase derivada de la pagina en el code behind
- Implementar los métodos RaiseCallbackEvent/GetCallbackResult
- Para recuperar los resultados del callback, se debe agregar lógica del lado del cliente para invocar el evento que hará la llamada al servidor
- Escribir un método en JavaScript para procesar el resultado del Callback
- Utilizar el método ClientScript.GetCallbackEventReference para recuperar el nombre del método que hará el llamado al servidor.
Veamos a continuación como realizar estos pasos en la práctica. Comenzaré
explicando brevemente cual es modo de funcionamiento del ejemplo que voy a
realizar: (Ver Figura 2)
En la aplicación de ejemplo que construiremos básicamente tendremos una página
que contendrá dos controles: un “dropdownlistbox” y un “detailsView”. El objetivo es
recuperar la información detallada del cliente que se selecciona en la lista (Maestro-
Detalle) pero sin refrescar todo el contenido de la página (Nota: El código de ejemplo
lo podrán bajar en el link que aparece al final del presente artículo). Para lograr dicho
objetivo utilizaremos los siguientes componentes en la aplicación:
Veamos ahora que tenemos que incluir en el codigo de la pagina para poder utilizar
- Una página con los controles anteriormente mencionados, que también implemente la interfaz ICallBackEventHandler para poder utilizar los callbacks.
- Una clase llamada cliente, la cual será utilizada para recuperar la información de un cliente.
- Dos archivos XML, que funcionaran como nuestra base de datos.
callbacks:
Imports System.Text Imports System.IO Partial Class EjemploconCallback Inherits System.Web.UI.Page Implements ICallbackEventHandler Private _callbackArgument As String Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult Return _callbackArgument End Function Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent Try If eventArgument <> String.Empty Then Dim obj As New ObjectDataSource("Cliente", "obtieneDatosCliente") obj.SelectParameters.Add(New Parameter("pIdCliente", TypeCode.Int32, eventArgument)) DetailsView1.DataSource = obj DetailsView1.DataBind() Dim sr As New StringWriter() Dim htm As New HtmlTextWriter(sr) DetailsView1.RenderControl(htm) htm.Flush() _callbackArgument = sr.ToString() End If Catch ex As Exception Throw ex End Try End Sub Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim sb As New StringBuilder sb.Append(" function llamarServidor(arg) { " & vbCrLf) sb.Append(ClientScript.GetCallbackEventReference(Me, "arg", "Obtienedatos", "null", False)) sb.Append(";" & vbCrLf & "}" & vbCrLf) Page.ClientScript.RegisterClientScriptBlock(GetType(String), "llamarServidor", sb.ToString, True) DropDownList1.Attributes.Add("onchange", "llamarServidor(document.getElementById('" & DropDownList1.ClientID & "').value);return false;") End Sub End ClassVayamos paso a paso revisando el código anteriormente presentado. En primer lugar
noten ustedes que la pagina implementa la interfaz ICallbackEventHandler la cual nos
obliga a declarar dos métodos “RaiseCallbackEvent” y “GetCallbackResult”
(Importante! , para los que aun utilizan la versión beta probablemente
encontraran un error al compilar este código, esto por que en las versiones beta
solo se necesitaba utilizar el evento RaiseCallbackEvent y este retornaba un
valor de tipo string, esto cambió en la versión final RTM por que se dividió en los
dos métodos mencionados anteriormente, esto se utiliza para poder permitir
invocaciones asíncronas para obtener el resultado).
El evento “RaiseCallbackEvent” es el que se invoca cuando llega un callback
solicitado por el cliente, es aquí donde procesamos la lógica del lado del servidor,
noten ustedes el argumento, este es el valor que el cliente esta enviando. En este
evento hay una particularidad que creo pertinente explicarla, noten ustedes que en este
evento estoy instanciando un objeto de tipo ObjectDataSource, este lo utilizare para
hacer el binding al DetailsView, este objeto se conecta con la clase Cliente y manda
como valor por defecto al método “obtieneDatosCliente” el valor recibido que el
cliente envía (en este caso el id del cliente seleccionado en el dropdownlist), luego
utilizo el método RenderControl el cual esta implementado por la mayoría de
controles de ASP.NET, este método sirve para obtener el código HTML que el mismo
debe generar y esta es la respuesta de vuelta que enviaremos al cliente. El evento
GetCallBackResult es utilizado para enviar el valor de respuesta hacia el cliente.
También noten ustedes que en el evento “Page_Load” estoy utilizando dos nuevas
funciones incluidas en ASP.NET 2.0, estudiémoslas detenidamente:
Con el código anterior hemos cubierto los pasos del 1 al 3 y también el paso 5. El
- ClientScript.GetCallbackEventReference: Esta función es utilizada para poder inyectar en la pagina la función necesaria para poder hacer realidad un “Callback”. Enfoquémonos en el segundo y tercer argumento. El segundo argumento es el valor que enviaremos al servidor desde el cliente (En nuestro ejemplo el id del cliente seleccionado en el dropdownlist), en el tercer argumento indicamos como se llamara la función definida en el cliente que capturara la respuesta enviada del servidor (mas adelante verán como se define esta función).
- ClientScript.RegisterClientScriptBlock: Esta función nos facilita la vida para poder registrar en la página código de javascript.
- Attributes.Add: Este método es utilizado para agregar un atributo a un control, en este caso añadimos el evento “onchange”, el cual se procesa de lado del cliente; y este invoca la función que hará el callback hacia el servidor. Noten que utilizo la propiedad “ClientID”, esto por que ASP.NET le asigna un identificador único a cada control de la página.
único paso pendiente es el 4, el cual consiste en escribir una función en javascript para
capturar el valor de retorno que envía el servidor. Veamos el código:
<script language = "javascript"> function Obtienedatos(arg) { var info = document.getElementById('datosCliente'); info.innerHTML = arg; } </script>Si recuerdan en la sección de código anterior, mencionaba el uso del método
ClientScript.GetCallbackEventReference, el tercer argumento que recibe el mismo
indica como se llamara la función que se invocara del lado del cliente para procesar la
respuesta, en este caso “ObtieneDatos”. Ésta por omisión recibe un argumento que es
el string enviado por el servidor. En este caso es el html generado por el control
DetailsView. La magia la complementamos con una sección <div> en la cual
incluimos el control DetailsView, utilizamos el modelo DOM para poder acceder y
modificar dinámicamente el contenido de la página del lado del cliente (DHTML).
Como podrán observar el poder realizar un proceso asíncrono de llamadas al servidor
en ASP.NET 2.0 es ahora muy sencillo, basta con seguir los 5 pasos mencionados
anteriormente y por lo demás no nos preocupamos. Realmente es una ventaja que ésta
funcionalidad ya este incluida en el modelo de desarrollo, pues normalmente otras
implementaciones existentes, exigen que se incluyan archivos o referencias
adicionales para que pueda ser funcional.
Espero haber expuesto los puntos más relevantes para poder comenzar a utilizar script
callbacks con ASP.NET 2.0, ustedes mejor que nadie sabrán juzgar sobre este
beneficio adicional que nos ofrece el modelo de programación.
Happy Programming !!!
Ing. Carlos A. Lone
Guatemala
http://carloslone.somee.com
http://blog.contoso.net/dotnetmaniagt
Referencias:
Articulo de Jesse James: http://www.adaptivepath.com/publications/essays/archives/000385.php
Microsoft invented ajax: http://garrettsmith.net/blog/archives/2006/01/microsoft_inven_1.html
ASP.NET 2.0 Tutorial “Tips and Tricks section“: http://www.asp.net/QuickStart/aspnet/doc/tipstricks/default.aspx
Fichero con el código de ejemplo: carlone_ScriptCallbacks_VB.zip - 44 KB
(MD5 checksum: [F6F7A3C8E540B53CF95B7D144450B41D])