jueves, 16 de octubre de 2014

El Demo del Día: Programación Asíncrona en ASP .NET con XmlHttpRequest

Programación Asíncrona en ASP .NET con XmlHttpRequest

En este breve post veremos como hacer un envío asíncrono usando XmlHttpRequest, para los que no conocen que es, es el padre de AJAX y fue creado por Microsoft por el año 2000 para usarlo en Outlook Web Access (OWA) que era un cliente de correo. Uno de los integrantes y líder del equipo que desarrollo XmlHttp es Alex Hopmann, para mayor información visitar su web:
Alex Hopmann

Requerimiento

Se desea registrar el nombre y la observación de una persona en el servidor, sin hacer un Full PostBack ni refrescar toda la pagina cuando se muestre el resultado, es decir, se desea hacer un envío y recepción asíncrona en forma nativa con HTTP.

Solución

Para enviar asíncronamente datos desde el Cliente Web (Navegador o Browser) hacia el Servidor Web podemos usar XmlHttpRequest desde JavaScript, en cualquier tipo de aplicación del servidor, sea ASP .NET, Java o PHP.

Crear la Aplicación Web en ASP .NET Web Form

Crear un "Nuevo Sitio web vacío de ASP .NET" en C# o VB.NET (en mi caso esta en VB.NET) llamado "Asincrono_XmlHttpRequest":

Nota: Conseguir una imagen para la espera llamada: Progress.gif

Cambiar de nombre a la pagina por "Registro.aspx" y realizar el siguiente diseño:


Para lograr el diseño mostrado, escribir el siguiente HTML:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Registro.aspx.vb" Inherits="Registro" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <script>
        function enviarDatos() {
            var nombre = document.getElementById("txtNombre").value;
            var observacion = document.getElementById("txtObservacion").value;
            var espera = document.getElementById("divEspera");
            var xhr = new XMLHttpRequest();
            xhr.open("get", "Registro.aspx?nombre=" + nombre + "&observacion=" + observacion,true);
            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xhr.onloadstart = function () { espera.style.display = "inline"; }
            xhr.onloadend = function () { espera.style.display = "none";  }
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var spn = document.getElementById("lblMensaje");
                    spn.innerHTML = xhr.responseText;
                }
            }
            xhr.send();
            return false;
        }
    </script>
</head>
<body style="background-color:aqua">
    <form id="form1" runat="server">
    <div>
        <h1>Envio Asincrono con XmlHttpRequest</h1>
        <h2>Registro de Datos</h2>
        Nombre:<br />
        <asp:TextBox ID="txtNombre" Width="300" runat="server" /><br/>
        Observacion: <br />
        <asp:TextBox ID="txtObservacion" Width="300" TextMode="MultiLine"
           Rows="5" runat="server" /><p />
        <input id="btnGrabar" type="submit" value="Grabar"
           onclick="return enviarDatos();" runat="server" />
        <p />
            <asp:Label ID="lblMensaje" runat="server"></asp:Label>
    </div>
    <div id="divEspera" style="display:none;text-align:center;position:fixed;left:0px;top:0px;
       width:100%;height:100%;background-color:gray;">
        <h1>Espera un momento...</h1>
        <img src="Progress.gif" width="600" height="400" alt="" />
    </div>
    </form>
</body>
</html>

Nota: La función "enviarDatos" se esta asociando al evento "click" del botón para realizar el envio asíncrono usando el método send de la clase XMLHttpRequest. Además para recibir la respuesta del servidor se esta usando el evento "onreadystatechange" en donde se escribe HTML sobre la etiqueta "lblMensaje".

Escribir código en Visual Basic (o C#) para devolver los resultados, no sin antes hacer una pausa simulando la demora del servidor, tal como sigue:

Partial Class Registro
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
        Dim Nombre As String = Request.QueryString("nombre")
        Dim Observacion As String = Request.QueryString("observacion")
        If Nombre IsNot Nothing Then
            System.Threading.Thread.Sleep(3000)
            Response.Write(String.Format("{0} escribio {1}", Nombre, Observacion))
            Response.End()
        End If
    End Sub
End Class

Nota: Para devolver los resultados del servidor al cliente estamos usando el objeto Response con sus métodos write para escribir la salida y end para enviarla al cliente.

Probar la Pagina Web

Guardar el Sitio Web, clic derecho a la Pagina "Registro.aspx" y seleccionar "Ver en el explorador".
Se mostrará una ventana similar a la mostrada en la siguiente figura:


Ingresar el nombre y la observación y luego clic al botón "Grabar" para realizar el envío de datos asíncrono al servidor. Observen que no se mueve el botón de Refresh del navegador, es decir no se hace un Full PostBack.

Luego, parecerá la pantalla de espera (div) con la imagen del progreso, tal como se muestra en la siguiente figura:


Después de los 3 segundos de espera se mostrará el resultado final sin refrescar toda la pagina, tal como se muestra en la siguiente figura:


Comentario Final

En este pequeño demo hemos visto como podemos llamar y recibir datos en forma asíncrona usando la API de HTML llamada XMLHttpRequest, la cual es nativa y actualmente es soportada por todos los navegadores modernos: Chrome, Firefox, Safari e Internet Explorer.

Esta forma de uso es mas ligera por ser nativa, pero no es tan difundido su uso por un poco de desconocimento (como todas las cosas), la mayoría conoce a los hijos de XMLHttpRequest que son jQuery ($.ajax, $.get, $.post, etc) y Microsoft AJAX Library (ScriptManager, UpdatePanel, Sys, etc).

Descarga:
Demo21_Asincrono_XmlHttpRequest

El Libro del Día: The Art of Unit Testing

El Libro del Día: 2014-10-16

Titulo: The Art of Unit Testing (Second Edition)
Autor: Roy Osherove
Editorial: Manning
Nro Paginas: 294

Capítulos:
PART 1 GETTING STARTED
1 The basics of unit testing
2 A first unit test
PART 2 CORE TECHNIQUES
3 Using stubs to break dependencies
4 Interaction testing using mock objects
5 Isolation (mocking) frameworks
6 Digging deeper into isolation frameworks
PART 3 THE TEST CODE
7 Test hierarchies and organization
8 The pillars of good unit tests
PART 4 DESIGN AND PROCESS
9 Integrating unit testing into the organization
10 Working with legacy code
11 Design and testability

Descarga:
The_Art_Of_Unit_Testing