lunes, 2 de diciembre de 2013

Ejecutar servicio WCF con Jquery

Les mostrare un ejemplo práctico de como ejecutar servicio WCF desde Jquery  ,el cual nos permite hacer llamados asíncronos al servidor desde un webform en asp.net .

Aspx :

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AJAXJQuery.aspx.cs" Inherits="TestJquery1.AJAXJQuery" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head runat="server">
    <title>AJAX JQuery</title>
    <script type="text/javascript" src="Scripts/jquery-1.6.1.min.js"></script>
    <script type="text/javascript" language="javascript">
        $(document).ready(function () {
            /***************************************
            Llamado AJAX Service Method WebForm
            ****************************************/
            $("#BtGetData").click(function () {
                $("#DivPersons").html("");
                $.ajax({
                    //Permite definir el tipo de llamado GET o POST siendo POST el mejor
                    type: "POST",
                    //Define la ruta al WebMethod existente en el code-behind
                    url: "AJAXJQuery.aspx/GetPersons",
                    //Permite pasar parametro en formato JSON (string) Hay Utilities como JSON2,
                    //que permite serializar falcilmente a este fomato
                    data: {},
                    //Define el content type que viajara en los bloques HTTP
                    contentType: "application/json; chartset:utf-8",
                    //Define el tipo de datos que se va a manejar xml, json
                    dataType: "json",
                    //Esta sección permite definir una función anónima, la cual se encargará de
                    //recibir los resultados provenientes del servidor,
                    //en este caso serializados en formato JSON
                    success:
                        function (result) {
                            if (result.d) {
                                var table = $("<table></table>");
                                table.append($("<tr style='background:#EBEBEB;'></tr>").append("<td>Código</td><td>Nombre</td>"))
                                $(result.d).each(function () {
                                    table.append($("<tr></tr>").append("<td>" + this.Id + "</td><td>" + this.Name + "</td>"));
                                });
                                $("#DivPersons").append(table);
                            }
                        },
                    //Esta función permite definir una función anónima que
                    //se encargara de gestionar los posibles erroes.
                    error:
                    function (XmlHttpError, error, description) {
                        $("#DivPersons").html(XmlHttpError.responseText);
                    },
                    async: true
                });
            });
 
/*****************************************************
            Llamado AJAX Servicio ASMX
            Es importante descomentar :  [System.Web.Script.Services.ScriptService]
            En la clase del servicio, pues esto habilita la
            funcionalidad  AJAX.
            ******************************************************/
            $("#TextBoxDesc").blur(function () {
                $.ajax({
                    //Permite definir el tipo de llamado GET o POST siendo POST el mejor
                    type: "POST",
                    //Define la ruta al WebMethod existente en el Servicio ASMX
                    url: "Service/WebServicePerson.asmx/HelloWorld",
                    //Permite pasar parametro en formato JSON (string) Hay Utilities como JSON2,
                    //que permite serializar falcilmente a este fomato
                    data: '{ "name":"' + $(this).val() + '" }',
                    //Define el content type que viajara en los bloques HTTP
                    contentType: "application/json; chartset:utf-8",
                    //Define el tipo de datos que se va a manejar xml, json
                    dataType: "json",
                    //Esta sección permite definir una función anónima, la cual se encargará de
                    //recibir los resultados provenientes del servidor, en este caso
                    //serializados en formato JSON
                    success:
                        function (result) {
                            if (result.d) {
                                alert(result.d);
                            }
                        },
                    //Esta función permite definir una función anónima que se
                    //encargara de gestionar los posibles erroes.
                    error:
                    function (XmlHttpError, error, description) {
                        $("#DivPersons").html(XmlHttpError.responseText);
                    },
                    async: true
                });
            });
 
            /*****************************************************
            Llamado AJAX Servicio WCF
            Ver WebConfig para la definición de los parámetros
            de configuración.
            ******************************************************/
            $("#TxtDetailsPerson").blur(function () {
                $("#DivPersonsByFilter").html("");
                $.ajax({
                    //Permite definir el tipo de llamado GET o POST siendo POST el mejor
                    type: "POST",
                    //Define la ruta al WebMethod existente en el code-behind
                    url: "Service/ServicePerson.svc/GetPersonByFilter",
                    //Permite pasar parametro en formato JSON (string)
                    data: '{ "filter":"' + $(this).val() + '"}',
                    //Define el content type que viajara en los bloques HTTP
                    contentType: "application/json; chartset=utf-8",
                    //Define el tipo de datos que se va a manejar xml, json
                    dataType: "json",
                    //Esta sección permite definir una función anónima,
                    //la cual se encargará de recibir los resultados provenientes
                    //del servidor, en este caso serializados en formato JSON
                    success:
                        function (result) {
                            if (result) {
                                var table = $("<table></table>");
                                table.append($("<tr style='background:#EBEBEB;'></tr>").append("<td>Código</td><td>Nombre</td>"))
                                $(result.GetPersonByFilterResult).each(function () {
                                    table.append($("<tr></tr>").append("<td>" + this.Id + "</td><td>" + this.Name + "</td>"));
                                });
                                $("#DivPersonsByFilter").append(table);
                            }
                        },
                    //Esta función permite definir una función anónima que
                    //se encargara de gestionar los posibles erroes.
                    error:
                    function (XmlHttpError, error, description) {
                        $("#DivPersonsByFilter").html(XmlHttpError.responseText);
                    },
                    async: true
                });
            });
        });
    </script>
</head>

 
body>
    <form id="form1" runat="server">
    Consultar todas las persona:<br />
    <asp:Button ID="BtGetData" runat="server" OnClientClick="return false;" Text="WebMethod JQuery" />
    <br />
 
    <br />
    <div id="DivPersons">
    </div>
    <br />
    ASMX JQuery<br />
    WebMethod<br />
    Cuál es tu nombre?:<br />
    <asp:TextBox ID="TextBoxDesc" runat="server" ></asp:TextBox>
    <div id="DivASMXHelloWorld">
    </div>
    <br />
    <br />
    WCF - JQuery <br />
    Windows Comunication Foundation WebInvoke
    <br />
    Consultar personas por filtro de búsqueda:<br />
    <asp:TextBox ID="TxtDetailsPerson" runat="server" ></asp:TextBox>
    <div id="DivPersonsByFilter">
    </div>
 
    </form>
</body>
</html>

Modelo de datos usado Class Person
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
namespace TestJquery1
{
    /// <summary>
    /// Clase que permite simular el acceso a datos
    /// </summary>
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        /// <summary>
        /// Inicializa la simulación de un contexto de datos
        /// </summary>
        /// <returns></returns>
        public List<Person> GetPersons()
        {
            List<Person> persons = new List<Person>();
            persons.Add(new Person { Id = 1, Name = "Pedro" });
            persons.Add(new Person { Id = 2, Name = "Andrés" });
            persons.Add(new Person { Id = 3, Name = "Juan" });
            persons.Add(new Person { Id = 4, Name = "Julián" });
            persons.Add(new Person { Id = 5, Name = "Felipe" });
            return persons;
        }
        /// <summary>
        /// Permite filtrar personas y realizar una búsqueda
        /// tanto por Cod si el filtro es numerico o por
        /// coincidencia con el nombre si el filtro es texto
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public List<Person> PersonsByFilter(string filter)
        {
            double id = -1;
            string name = string.Empty;
            var persons = GetPersons();
            if (Double.TryParse(filter, out id))
            {
                var result = from p in persons
                             where p.Id == id
                             select p;
                return result.ToList();
            }
            else {
                var result = from p in persons
                             where p.Name.Contains(filter)
                             select p;
                return result.ToList();
            }
        }
    }
}
(Code Behind) Static WebMethod
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Services;
 
namespace TestJquery1
{
    public partial class AJAXJQuery : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
 
        }
        /// <summary>
        /// Método de servicio
        /// </summary>
        /// <returns></returns>
        [WebMethod]
        public static List<Person> GetPersons()
        {
            Person person = new Person();
            var list = person.GetPersons();
            return list;
        }
    }
 
}
ASMX Service Code-Behind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
 
namespace TestJquery1.Service
{
    /// <summary>
    /// Summary description for WebServicePerson
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    [System.Web.Script.Services.ScriptService]//Es importante descomentar esta linea si es que está comentada
    public class WebServicePerson : System.Web.Services.WebService
    {
 
        [WebMethod]
        public string HelloWorld(string name)
        {
            return String.Format("Hello World {0}, te saludo desde un ASMX Service", name);
        }
    }
}
WCF Code Behind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
 
namespace TestJquery1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IServicePerson" in both code and config file together.
    [ServiceContract]
    public interface IServicePerson
    {
        [OperationContract]
        [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
        List<Person> GetPersonByFilter(string filter);
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
 
namespace TestJquery1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "ServicePerson" in code, svc and config file together.
    public class ServicePerson : IServicePerson
    {
        public List<Person> GetPersonByFilter(string filter)
        {
            Person persons = new Person();
            var personsList = persons.PersonsByFilter(filter);
            return personsList;
        }
    }
}
 
Es necesario configurar los servicios de WCF de forma tal que sean accesibles desde el Browser, como aclaración es necesario configurar los endpoints y bindings correspondiente al servicio, así cómo establecer la propiedad <serviceMetadata httpGetEnabled=”True/> lo cual habilitara la definición del documento WSDL el cual contendrá la Metadata del Servicio
 
<system.serviceModel>
   <behaviors>
     <serviceBehaviors>
       <behavior name="ServicePersonBeheavor">
         <serviceMetadata httpGetEnabled="True"/>
         <serviceDebug includeExceptionDetailInFaults="True"/>
       </behavior>
     </serviceBehaviors>
     <endpointBehaviors>
       <behavior name="ServicePersonBeheavor">
         <webHttp/>
       </behavior>
     </endpointBehaviors>
   </behaviors>
   <services>
     <service behaviorConfiguration="ServicePersonBeheavor" name="TestJquery1.ServicePerson">
       <endpoint address="" binding="webHttpBinding" contract="TestJquery1.IServicePerson" behaviorConfiguration="ServicePersonBeheavor"></endpoint>
     </service>
   </services>
 </system.serviceModel>
 

No hay comentarios: