Colaboraciones en el Guille

Script Callbacks en ASP.NET 2.0

 

Fecha: 31/Ene/2006 (30/01/2006)
Autor: Carlos A. Lone, [email protected]

 


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.

Diferencia entre un Postback y un Callback


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:

  1. Implementar la interfase ICallBackEventHandler en la clase derivada de la pagina en el code behind
  2. Implementar los métodos RaiseCallbackEvent/GetCallbackResult
  3. 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
  4. Escribir un método en JavaScript para procesar el resultado del Callback
  5. 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)


Diagrama de la aplicacion de ejemplo

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
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 Class

Vayamos 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
ú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])


ir al índice principal del Guille