AJAX en ASP.NET 2.0 con Page Methods

12. December 2009 11:56 by Oscar.SS in Desarrollo Web  //  Tags:   //   Comments (0)

En el artículo anterior de esta serie vimos la potencia y facilitdad que nos ofrece un control UpdatePanel combinado con un ScriptManager. Pero no es oro todo lo que reluce. ¿Que sucede si tenemos una página con muchos controles pero solo queremos actualizar por AJAX uno de ellos?.

Tenemos que tener en cuenta que cuando utilizamos un UpdatePanel estamos enviando al servidor todo el HTML de la página. Es decir, no solo estamos enviando el contenido del UpdatePanel, enviamos también todos los controles que encuentran fuera. Y esto aumenta mucho el tráfico hacia el servidor. Además, en el servidor se disparan todos los eventos del ciclo de vida de la página y de todos los controles que contenga. Lo que recarga las funciones realizadas por el servidor.

Eso si, el servidor gracias al UpdatePanel y a las librerías cliente que nos ofrece el ScriptManager, solo envía el HTML necesario para actualizar los controles que se encuentren dentro del UpdatePanel.

Estas consideraciones debemos tenerlas en cuenta si estamos implementado AJAX en una página muy pesada con mucho controles. La implementación de los métodos de página o Page Methods nos ofrece la posibilidad de tener más control sobre la forma de actualizar la página a cambio de perder un poco de automatización.

 

 

 

Código Cliente

Lo primero que tenemos que hacer es habilitar la funcionalidad de los métodos de página en el control ScriptManager por medio de la propiedad EnablePageMethods.

    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
        
<Scripts>
            
<asp:ScriptReference Path="funcionesPageMethods.js" />
        </
Scripts>
    
</asp:ScriptManager> 

Por otro lado, hemos añadido una referencia al archivo JavaScript que contendrá las funciones necesarias para el envío y recogida de datos de forma asíncrona. Este es el código.

//Funcion que llama al método de la página de forma asíncrona.
function EnviarDatos() {

    
//$get('') == document.getElementById('')
    
var nombreSeleccionado $get("listaNombres").value;
    
    
//Llamada al metodo de la página.
    
PageMethods.ObtenerDatos(nombreSeleccionado, RecogerRespuesta, RecogerErrores);
}


//Funcion que recoge los datos desde el servidor.
function RecogerRespuesta(datosRecibidos)
{
    $
get("txRespuesta").innerText datosRecibidos;
}


//Función que recoge los posibles errores.
function RecogerErrores(error) {

    
alert("Error: " + error.get_message());
}

Ya estamos acostumbrados a este tipo de implementación, una función para enviar los datos asíncronos, otra para recogerlos y una función para recoger los errores que se produzcan durante la llamada. Lo único que merece la pena resaltar es esta linea.

 PageMethods.ObtenerDatos(nombreSeleccionado, RecogerRespuesta, RecogerErrores);

 

La clase PageMethods intrínseca de la librería ASP.NET AJAX nos permite llamar a la función ObetenerDatos() que es un método estático que se encuentra en nuestra página.

 

Código Servidor

En el código de servidor solo tendremos que implementar el método que se encarga de recoger los datos desde el cliente y enviarlos asíncronamente una vez manipulados de vuelta al cliente. 

    [System.Web.Services.WebMethod]
    
public static string ObtenerDatos(string nombreSelec)
    {
        
//Antes de enviar la petición simulamos una tarea larga.
        
System.Threading.Thread.Sleep(5000);
        
        return 
ManejarDatos.ObtenerCategoria(nombreSelec, rutaDatos);
    
}

Como vemos este método tiene que ser static y estar decorado con el atributo System.Web.Services.WebMethod.

 

Código de descarga 

El código completo mencionado en este artículo se encuentra en la carpeta AJAX_NET_3.5/Retro_Llamdas/AJAX_PageMethods del siquiente enlace. Para probar la aplicación ejecutar la página AJAX_PageMethods.aspx de la carpeta mencionada.

 

AJAX_ASP.NET.rar (15,45 kb)

Enviar datos asíncronos a un control fuera de un UpdatePanel

8. December 2009 17:48 by Oscar.SS in Desarrollo Web  //  Tags:   //   Comments (6)

Es posible que a muchos este título les suene a chino, y quizás también, no sea un caso que se de muy a menudo. Pero opino que es una característica que debemos conocer para tener más control sobre las aplicaciones ASP.NET AJAX.

 

El problema

Comenzemos plantenado el problema. Cuando utilizamos AJAX Extensions en una aplicación ASP.NET sabemos que en la respuesta asíncrona del servidor solo se envía de vuelta al cliente web una porción muy pequeña de HTML. Exactamente, solo se envía el HTML necesario para actualizar los controles que se encuentran dentro de un UpdatePanel, es lo que se conoce como repintado parcial. ¿Pero que ocurre si queremos, en algunas ocasiones, actualizar un control que se encuentra fuera de un UpdatePanel?. Es decir, ¿como podemos decirle al servidor que envíe otros datos además del HTML del repintado parcial?.

Veámoslo con un pequeño ejemplo.

    <div>
        
<asp:TextBox ID="TextBox1" runat="server">
            
</asp:TextBox><asp:Button ID="Button1" runat="server" Text="Button" 
            onclick
="Button1_Click" />
        <
br />
        <
br />
    
<!-----------Sección que se actualiza por AJAX (repintado parcial)--------------->
        
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
            
<ContentTemplate>
                
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
            
</ContentTemplate>
            
<Triggers><asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" /></Triggers>
        
</asp:UpdatePanel>
    
<!-------------------------------------------------------------------------------->    
        
<br />
        <
br />
        <
asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
    
</div>

 

¿Que tenemos aquí?. Tenemos un TextBox donde el usuario introducirá su nombre y tenemos dos Labels que mostrarán un saludo al usuario cuando hagan Click sobre el Button. Como podemos observar uno de los Labels se encuentra dentro de un UpdatePanel y el otro fuera. El que esta dentro se aprovechará de la funcionalidad de AJAX para actualizar su contendido de manera asíncrona.

Añadamos código para manejar el evento del Button y veamos que sucede.

 

        protected void Button1_Click(object sender, EventArgs e)
        {
            
string datosEnviados "Hola " + TextBox1.Text;

            
Label1.Text datosEnviados;
            
Label2.Text datosEnviados;
        
}

 

Al ejecutarse el evento vemos que solo se actualiza el Label1. El Label2 no se entera de nada. ¿Porque?.

Ya lo hemos comentado ante. El servidor solo está enviando al cliente el HTML necesario para actualizar los controles que se encuentran dentro del UpdatePanel.Repito la pregunta, ¿como podemos decirle al servidor que envíe otros datos además del HTML del repintado parcial?.

 

La solución

Cambiamos el código del evento del Button por el siguiente:

            string datosEnviados "Hola " + TextBox1.Text;
            
Label1.Text datosEnviados;

            
ScriptManager1.RegisterDataItem(Label2, datosEnviados);

El método RegisterDataItem() del ScriptManager envía datos en una llamanda asíncrona a los controles que se encuentran fuera del UpdatePanel. Ahora debemos manegar el siguiente evento en el cliente.

    <script type="text/javascript" language="javascript">
        Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(RecogerDatosHandler)
;

        function 
RecogerDatosHandler(sender, args) {
            
var datos args.get_dataItems();
            
$get("Label2").innerHTML datos["Label2"];
        
}
    </script>

En primer lugar obtenemos una instancia de la clase Sys.WebFroms.PageRequestManager que es la encargada de actualizar los controles que se encuentran dentro del UpdatePanel. Antes de que esta actualización ocurra, gestionamos el evento pageLoading() y recogemos los datos enviados desde el servidor para actualizar el Label2.

Hemos creado nuestro propio manejador del evento, RecogerDatosHandler(), que por medio del la colección args podemos acceder a los datos enviados desde el servidor.

Nota: La definición del script cliente anterior debe colocarse después de la definición del controls ScriptManager, de lo contrario nos dará un error diciendo que el espacio de nombres Sys no está definico aún, ¡como es lógico!.

 

GridView: acceder a los valores de las columnas no visibles

6. December 2009 15:26 by Oscar.SS in Desarrollo .NET, Desarrollo Web  //  Tags: ,   //   Comments (0)

Cuando intentamos acceder al valor de una celda, de una columna marcada en el GridView como no visible, nos encotramos ante un problema. Dado que, normalmente las columnas marchadas como no visibles, suelen almacenar datos nada importantes para el usuario (id, codigos, valores ocultos, etc) pero si de suma importancia para el funcionamiento interno de nuestra aplicación.

Por lo tanto, lógicamente el siguiente intento no nos devolverá nada porque la columna no visible no ha sido "pintada".

string id gvEmpleados.Rows[e.RowIndex].Cells[celdaId].Text;

Para resolver este pequeño problema debemos utilizar las propiedades DataKayNames y Datakeys del GridView. Veamos un ejemplo.

Tenemos el siguiente XML que deseamos mostrar por pantalla al usuario por medio de una rejilla como GridView.

<?xml version="1.0" encoding="utf-8"?>
<empleados>
    
<empleado id="1" idEmpresa="034/9435" Nombre="Pedro" Telefono="985945452" Pais="Mexico" />
    <
empleado id="2" idEmpresa="035/3245" Nombre="Antonio" Telefono="887404730" Pais="Perú" />
    <
empleado id="3" idEmpresa="078/4324" Nombre="Jorge" Telefono="9149858353" Pais="España" />
    <
empleado id="4" idEmpresa="045/3243" Nombre="Elena" Telefono="893737581" Pais="Argentina" />
    <
empleado id="5" idEmpresa="074/5425" Nombre="Raquel" Telefono="9984573423" Pais="España" />
</
empleados> 

Nuestro GridView tendrá la siguiente definición de código HTML en nuestra página.

 

<asp:GridView ID="gvEmpleados" runat="server" AutoGenerateColumns="False" 
            DataSourceID
="XmlDataSourceEmpleados" DataKeyNames="id,idEmpresa" 
            onrowdeleting
="gvEmpleados_RowDeleting" 
            onselectedindexchanging
="gvEmpleados_SelectedIndexChanging">
            
<Columns>
                
<asp:CommandField ShowSelectButton="True" />
                <
asp:BoundField DataField="id" HeaderText="id" SortExpression="id" 
                    Visible
="False" />
                <
asp:BoundField DataField="idEmpresa" HeaderText="idEmpresa" 
                    SortExpression
="idEmpresa" Visible="False" />
                <
asp:BoundField DataField="Nombre" HeaderText="Nombre" 
                    SortExpression
="Nombre" />
                <
asp:BoundField DataField="Telefono" HeaderText="Telefono" 
                    SortExpression
="Telefono" />
                <
asp:BoundField DataField="Pais" HeaderText="Pais" SortExpression="Pais" />
                <
asp:CommandField ShowDeleteButton="True" />
            </
Columns>
        
</asp:GridView>
        
<asp:XmlDataSource ID="XmlDataSourceEmpleados" runat="server" 
            DataFile
="~/App_Data/empleados.xml"></asp:XmlDataSource>
He marcado en negrita y un poco más grande las columnas no visibles al usuario. También podemos ver la propiedad DataKeyNames. Esta propiedad permite establecer (también recuperar) una colección de columnas que serán tratadas como claves primarias del origen de datos.
 
Ahora solo nos queda desde código acceder a estos valores cuando el usuario dispare cualquiera de los eventos del GridView. Ya sea para actualizar, eliminar, seleccionar, etc una fila. Un par de ejemplos:
 
 
    protected void gvEmpleados_SelectedIndexChanging(object sender, GridViewSelectEventArgs e)
    {
        var colsNoVisible 
gvEmpleados.DataKeys[e.NewSelectedIndex].Values;
        string 
id (string)colsNoVisible[0];
        string 
idEmpresa (string)colsNoVisible[1];
    
}
    
protected void gvEmpleados_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
        var colsNoVisible 
gvEmpleados.DataKeys[e.RowIndex].Values;
        string 
id (string) colsNoVisible[0];
        string 
idEmpresa (string) colsNoVisible[1];
    
}

La propiedad DataKeys nos permite acceder a las columnas que son tratadas como claves primarias en el origen de datos. De esta forma nosotros podemos trabajar por debajo con registros únicos como ids y mostrar al usuario solo la información que le interesa.

 

AJAX en ASP.NET 2.0 con AJAX Extensions

14. November 2009 13:03 by Oscar.SS in Desarrollo Web  //  Tags:   //   Comments (0)

Quizás aquí algunos esperaban erroneamente que el título hablara de ASP.NET 3.5 pero como ya he comentado alguna vez (creo!!), las versiones de ASP.NET saltan de la 2.0 a la 4.0. No así las versiones de la plataforma .NET que si han seguido un camino más continuado 2.0, 3.0, 3.5, y 4.0.

Por lo tanto, este árticulos y los siguientes tratarán de lo que se puede hacer con AJAX en ASP.NET 2.0 con el framework 3.0 o 3.5. Por otra parte, igualmente válido son para aquellos que trabajan con ASP.NET 2.0 sobre .NET 2.0 y tienes instaladas las plantillas AJAX Extensions. (Ver gráfico evolución plataforma)

 

 

Código Cliente

En este caso el código cliente se redece a incluir un control ScriptManager y un control UdatePanel dentro del cuerpo de la página.

    <form id="form1" runat="server">
    
<asp:ScriptManager ID="ScriptManager1" runat="server">
    
</asp:ScriptManager>
    
<div>
        
<p style="text-align:center; font-size:xx-large; color:Blue; text-decoration:underline">AJAX con AJAX Extensions</p>
        
<span>Seleccionar un nombre:</span>
        
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" 
            onselectedindexchanged
="DropDownList1_SelectedIndexChanged">
            
<asp:ListItem Selected="True">Oscar</asp:ListItem>
            
<asp:ListItem>David</asp:ListItem>
            
<asp:ListItem>Diego</asp:ListItem>
            
<asp:ListItem>Sergio</asp:ListItem>
            
<asp:ListItem>Luis</asp:ListItem>
        
</asp:DropDownList>
        
<br />
        <
br />
        <
asp:UpdatePanel ID="UpdatePanel1" runat="server">
            
<ContentTemplate>
                Categoria profesional:  
<asp:Label ID="Label1" runat="server" ForeColor="Red"></asp:Label>
            
</ContentTemplate>
            
<Triggers><asp:AsyncPostBackTrigger ControlID="DropDownList1" 
                    EventName
="SelectedIndexChanged" /></Triggers>
        
</asp:UpdatePanel>
        
<br />
        <
br />
        <
span>Mientras se ejecuata la petición de datos escribir aquí para comprobar el AJAX.</span>
        
<input id="Text1" type="text" />
    </
div>
    
</form>


El control ScriptManager es el encargado de registrar en el cliente todo el código script necesario para soportar AJAX.  Debe aparecer antes que ningún otro control en la página.

En el control UpdatePanel, dentro de <ContentTamplate>, incluiremos únicamente el contenido HTML que deba ser actualizado cuando el servidor devuelva los datos. Este control se encarga de enviar desde el servior solo la porción de HTML que contiene, realizando lo que se denomina un repintado parcial de la página. Dentro de <Triggers> se declaran los controles y eventos que disparan este repintado parcial.

¡Y ya esta!. No hay que hacer nada más. No hay que escribir ni una linea de código cliente, entre el control ScriptManager y el UpdatePanel, se encargar de envíar los datos al servidor y de recibirlos mostrandolos al usuario.

 

Código Servidor

Y en el servidor no tenemos que hacer nada especial para manipular la funcionalidad AJAX. Simplemente incluiremos el código necesario dentro del evento del control que hemos declarado anteriormente dentro de <Triggers> en el UpdatePanel.

    protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        
string rutaDatos Server.MapPath("~/App_Data/datos.xml");

        string 
nombreSelec DropDownList1.SelectedValue;

        
//Antes de enviar la petición simulamos una tarea larga.
        
System.Threading.Thread.Sleep(5000);

        
Label1.Text ManejarDatos.ObtenerCategoria(nombreSelec, rutaDatos);
    
} 


Código de descarga 

El código completo mencionado en este artículo se encuentra en la carpeta AJAX_NET_3.5/AJAX_Extensions del siquiente enlace. Para probar la aplicación ejecutar la página AJAX_Extensions.aspx de la carpeta mencionada.

AJAX_ASP.NET.rar (15,45 kb)

El futuro de internet

2. November 2009 19:57 by Oscar.SS in Internet, Personal  //  Tags: ,   //   Comments (0)

Paseando por la red me he encontrado con este video que da un interesante repaso al comienzo de internet, y como no podía ser de otra manera, también da una visión futurista de internet.

A mí me ha parecido un poco exagerada esta visión. Mi opinión personal viene alimentada por las visiones futuristas de las películas de los años 80. Muchas películas de esta époco ponían al año 2000 ( como "Odisea en el espacio 2001") como un referente futurista, donde la inteligencia artificial y los viajes intergalácticos eran una realidad.

Han pasado nueve años desde el 2000 y todo sigue igual que siempre, exceptuando la fuerte entrada de este gigante de la información compartida que es internet. Os dejo con el video.

 

 

No sé si este será el futuro de internet, pero lo que tengo claro es que el futuro de la sociedad esta ligado al futuro de internet. ¡Espero que disfrutéis del video!.

  

Recent Comments

Comment RSS

Month List