AJAX constituye uno de los apéndices para el desarrollo de aplicaciones WEB, debido a que
ayuda a hacer eficientes las páginas aspx ¿por qué eficientes? Cuando trabajamos con comunicación normal entre el cliente y el servidor desde un Explorador Web como: IE, FireFox, Chrome etc, y necesitamos enviar una solicitud al servidor en la que pedimos por ejemplo los datos correspondientes al id de una persona, supongamos que tenemos un TextBox (se tarduce en un input type text de html) en el cual un usuario indica que su Id es 11 y pulse el botón Buscar en un formulario Web, solicitando que cómo resultado el servidor devuelva Nombre:David Peréz, Edad:10 años, Id:11 y luego en html presentar al usuario los resultados, entonces allí de forma normal se estaría haciendo un PostBack lo que se constituye como una petición web usando el protocolo http que en términos técnicos es el Request al servidor, si bien esto no tiene problemas, ocurre internamente que la página Web y su html se envía en bloques http al servidor, siendo esto una forma muy costosa de enviar los datos desde el cliente, de igual forma el resultado del servidor o lo que también pasamos a conocer cómo el Response, devuelve todo el html que el explorador pasa a pintar en el cliente haciendo el proceso de comunicación algo lento y de bajo performance.

Por lo tanto AJAX permite que el cliente envíe únicamente lo que en realidad desea enviar, que en este caso sería el id y que como resultado sólo se devuelvan los datos que indicamos anteriormente, para esto, en .NET tenemos varias alternativas, entre estas del lado del servidor crear un Servicio de tipo WCF, que va a permitir recibir los datos, procesar la petición y poder enviar un paquete serializado (Mediante un formato ligero cómo xml o en un mejor caso JSON) el cual contenga los datos que serán presentados al cliente en forma de html. Dicha comunicación podemos establecerla mediante Javascript usando por ejemplo ASP.NET Ajax library el cual se constituye como un API importante para el desarrollo de aplicaciones Web en el lado del cliente.

Código página ASPX

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AJAX.aspx.cs" Inherits="AJaxLib_RegClassInerz.AJAX" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Comunicación WCF y ASP.NET AJAX Library</title>

</head>
<body>
    <form id="form1" runat="server">
    <%--Con el objeto scriptmanager hacemos referencia al servicio de Windows Comunucation Foundation--%>
    <asp:ScriptManager ID="ScriptManager1" runat="server">
        <Services>
            <%--Hay que tener cuidado con la ruta relativa, en mi caso deje el servicio al mismo
            nivel que la página aspx--%>
            <asp:ServiceReference Path="~/ServiceSample.svc" />
        </Services>
    </asp:ScriptManager>

    <br/>
        <input id="Button5" type="button" runat="server" value="Saludar Persona" onclick="javascript:SayHello();" />
    <br />
        <input id="Button4" type="button" runat="server" value="Obtener datos Persona Id = 1" onclick="javascript:GetPerson();" />
    <br />
    <asp:Button ID="Button2" runat="server" Text="Obtener todas las personas" OnClientClick="javascript:GetPersons(); return false;" />
    <br />
    <asp:Button ID="Button3" runat="server" Text="Obtener todas las personas dentro de un Rango de Fechas" OnClientClick="javascript:GetPersonsByDateTime(); return false;" />
    <br />
    Resultados:
    <br />
    <%--Este objeto html permite agregar el contenido resultante de el llamado ajax--%>
    <div id="Result">
    </div>

    </form>
</body>
</html>

Código de ASP.NET AJAX Library en el Cliente

 <script type="text/javascript">
        var ServiceProxy;
        //Función relativa a windows.pageLoad
        function pageLoad() {

            //Inicializa es objeto correspondiente al servidio WCF
            ServiceProxy = new ServiceSample();

            //Establecemos el Manejador de resultado
            ServiceProxy.set_defaultSucceededCallback(ServiceCallSuccess);

            //Establecemos el manejador de errores
            ServiceProxy.set_defaultFailedCallback(OnErrorCallback);
        }

        function OnErrorCallback(error) {
            //Mostramos los errores ocurridos al cliente  si ocurren
            alert(error._message);
        }

        function ServiceCallSuccess(result, userContext, methodName) {
            var resultAJAX = document.getElementById("Result");
            resultAJAX.innerHTML = "";

            //Si los resultados son varios hacemos el recorrido y concatenamos el resultado
            if (methodName == "GetPersons" || methodName == "GetPersonsByDateTime") {
                for (var i = 0; i < result.length; i++) {
                    resultAJAX.innerHTML += result[i].FirstName + "<br/>";
                }
            }
            else if (methodName == "GetPerson") {
                resultAJAX.innerHTML += "Los datos de la persona son Nombre: " + result.FirstName + " Cumpleaños:" + result.HappyDay + " Id: " + result.Id;
            }
            else if (methodName == "SayHello") {
                resultAJAX.innerHTML += result;
            }
        }

        function SayHello() {
            //Enviamos un objeto persona al servidor de forma serializado
            //para procesar un saludo.
            var person = new AJaxLib_RegClassInerz.Person();
            person.Id = 10;
            person.FirstName = "Ingphillip ";
            person.HappyDay = "\/Date(" + Date.parse("04/12/1985") + ")\/";
            ServiceProxy.SayHello(person);
        }

        function GetPerson() {
            //Solicitamos la persona cuyo Id en el servidor es 1
            ServiceProxy.GetPerson(1);
        }

        function GetPersons() {
            //Solicitamos toda la lista de personas
            ServiceProxy.GetPersons();
        }

        function GetPersonsByDateTime() {
            //Solicitamos un grupo de personas que se encuentre entre un reango de edad
            ServiceProxy.GetPersonsByDateTime("\/Date(" + Date.parse("01/04/1980") + ")\/", "\/Date(" + Date.parse("21/02/1990") + ")\/");
            //De esta forma es posible serializar y pasar a WCF el tipo de dato Date
        }

    </script>

Código del Servicio WCF

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Text;

namespace AJaxLib_RegClassInerz
{
    /// <summary>
    /// Clase para la definición del servicio WCF la cual como atributo debe  tener
    /// [ServiceContract(Namespace = "")] para poder serializar el pasaje de datos y además
    /// [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    /// en donde estamos indicando que este servicio tendrá compatibilidad con ASP.NET.
    /// </summary>
    [ServiceContract(Namespace = "")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class ServiceSample
    {
        /// <summary>
        /// Esta será la simulación de los datos en el servidor.
        /// Una colección List de objetos del tipo Person declarado en la
        /// parte inferior
        /// </summary>
        List<Person> persons = new List<Person>(){
            new Person {
                Id = 1,
                FirstName = "Jose",
                HappyDay = Convert.ToDateTime("11/01/1998") },
            new Person {
                Id = 2,
                FirstName = "Antonio",
                HappyDay = Convert.ToDateTime("21/02/1990") },
            new Person {
                Id = 3,
                FirstName = "Hernando",
                HappyDay = Convert.ToDateTime("04/03/1995") },
            new Person {
                Id = 4,
                FirstName = "Felipe",
                HappyDay = Convert.ToDateTime("09/04/1985") }
        };

        /// <summary>
        /// Clase que recive un objeto
        /// serializado de tipo Persona
        /// desde el cliente
        /// </summary>
        /// <param name="person"></param>
        /// <returns></returns>
        [OperationContract]
        public string SayHello(Person person) {

            StringBuilder sb = new StringBuilder();
            TimeSpan ts = DateTime.Now - person.HappyDay;

            sb.Append(" Hello " + person.FirstName);
            sb.Append("\n Usted tiene " +  ts.Days / 365  + " años de edad ");
            sb.Append("\n Su Id es  " + person.Id);

            return sb.ToString();
        }
        /// <summary>
        /// Devuelve la lista de personas
        /// </summary>
        /// <returns></returns>
        [OperationContract]
        public List<Person> GetPersons()
        {
            return persons;
        }
        /// <summary>
        /// Devuelve una persona la cual se busca
        /// en la colección de personas y cuyo
        /// id corresponda con 1 por ejemplo
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [OperationContract]
        public Person GetPerson(int id) {
            var obj = persons.SingleOrDefault(p => p.Id == id);
            return obj;
        }

        /// <summary>
        /// Este méto especial va a devolver un grupo de
        /// personas las cuales su cumpleaños este entre el rango
        /// de dateTime1 y dateTime2
        /// </summary>
        /// <param name="dateTime1"></param>
        /// <param name="dateTime2"></param>
        /// <returns></returns>
        [OperationContract]
        public List<Person> GetPersonsByDateTime(DateTime dateTime1, DateTime dateTime2)
        {
            var pers = persons.Where(p => p.HappyDay >= dateTime1 && p.HappyDay <= dateTime2);
            return pers.ToList();
        }

    }
    /// <summary>
    /// Esta clase permite declarar el tipo de datos que se van a manejar
    /// en forma serializada entre el Cliente y el Servidor, para esto en
    /// WCF podemos declarar una clase con el atributo [DataContract],
    /// cada uno de los atributos de la clase debe tener el atributo [Datamember]
    /// lo que permitirá serializar cada propiedad.
    /// </summary>
    [DataContract]
    public class Person
    {
        int _id;
        [DataMember]
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }

        string _firstName;
        [DataMember]
        public string FirstName
        {
            get { return _firstName; }
            set { _firstName = value; }
        }

        DateTime _happyDay;
        [DataMember]
        public DateTime HappyDay
        {
            get { return _happyDay; }
            set { _happyDay = value; }
        }

    }
}

Anuncios