Seguimos con la serie de post sobre asp.net ajax. En esta ocasion usaremos las bondades que nos ofrece el Microsoft Ajax Framework asi que empecemos.
Usando capacidades de cliente de ASP.NET AJAX
En este ejercicio revisaremos la parte cliente del Microsoft AJAX Framework, el cual esta contenido en un archivo: MicrosoftAjax.js, es de saber que cuando uno de lado del servidor agrega el ScriptManager, automaticamente se agrega este archivo junto con MicrosoftAjaxWebForms.js.
Nota: Si establece la propiedad EnablePartialRendering = false no se agrega MicrosoftAjaxWebForms.js.
MicrosoftAjaxWebForms.js contiene el Javascript que da soporte al control UpdatePanel
Nota: Si no ha tenido experiencia en Javascript, se recomienda antes de comenzar este ejercicio leer los siguientes post:
http://msdn.microsoft.com/en-us/library/bb288795.aspx
http://msdn.microsoft.com/en-us/library/bb288796.aspx
Tarea 01 – Creacion del formulario y agregando Callbacks a los controles HTML
1. Agregaremos una nueva pagina (Ajax Web Form) a nuestro sitio web ClientMsAjax.aspx
2. Agregaremos un Input (button) HTML. (id=btnCallback, value="Hola MsAjax-Client")
3. Ahora nos ubicaremos en el javascript que se crea automaticamente creado por Visual Studio en un Ajax Web Form:
1: <script type="text/javascript">
2: function pageLoad() { }
3: </script>
4. Crearemos la funcion SayHelloTo con parametros event y context, la cual nos servira para el futuro callback al boton:
1: function sayHelloTo(event, context) {
2: alert("hola " + context + ", has hecho " + event.type + " desde aqui: " + this.id);
3: }
5. Dentro de la funcion pageLoad() añadiremos un evento al boton ya creado utilizando $addHandler. Previamente crearemos el callback correspondiente al evento:
1: var callback = Function.createCallback(sayHelloTo, "Gabo");
2: $addHandler($get("btnCallback"), "click", callback);
6. Adicionalmente agregaremos eventos de inicio y fin de la aplicacion:
1: Sys.Application.add_init(function()
2: { alert('Bienvenido a la demo de asp.net ajax'); });
3: Sys.Application.add_disposing(function() { alert('Hasta pronto.'); });
7. Ahora probaremos nuestra pagina web:
Analisis de la tarea 01
1. Hemos creado un evento para un boton, notese la firma de la funcion <Nombre_de_la_funcion>(event,context), en donde event contiene la informacion del evento y context los datos de parametro ingresado en Function.CreateCallback.
2. Para usar la el framework de Microsoft AJAX, simplemente agregamos el control ScriptManager a nuestro WebForm.
3. Microsoft AJAX tiene un metodo que hace las de document.getElementById() el cual es $get()
4. Para agregar eventos a los controles utilizamos $addHandler.
5. Function.CreateCallback(method, context) crea un metodo al que se le pasa un parametro a la funcion que administra el mismo
Tarea 02 – Llamada a WebMethods desde el cliente
En esta tarea haremos llamada a un metodo de nuestra pagina del servidor desde el cliente.
1. Agregaremos un Input (button) HTML. (id=btnGetTime, value="La hora del server")
2. En la seccion de codigo fuente, agregaremos el siguiente metodo
1: [System.Web.Services.WebMethod]
2: public static string GetTime()
3: {
4: return "La hora del servidor es: " + DateTime.Now;
5: }
3. Ahora en la seccion de javascript agregaremos las siguientes 3 funciones:
1: function getTime() {
2: PageMethods.GetTime(getTimeSuccess,getTimeFail);
3: }
4:
5: function getTimeFail(error) {
6: alert(error.get_message());
7: }
8:
9: function getTimeSuccess(result) {
10: $get("spanTime").innerHTML = result;
11: }
4. Dentro de la funcion pageLoad() ahora agregaremos el evento correspondiente a btnGetTime:
1: $addHandler($get("btnGetTime"), "click", getTime);
5. Modificaremos la propiedad EnablePageMethods=true del ScriptManager.
6. Ahora probaremos nuestra pagina:
Analisis de la tarea 02
1. Hemos llamado a un metodo de la pagina. Para esto el metodo debe estar ‘decorado†con el atributo [System.Web.Services.WebMethod]. A su vez debe ser estatico
2. Cuando la pagina expone un WebMethod, se autogenera la clase javascript PageMethods el cual contiene los metodos expuestos por la pagina.
3. Se puede especificar las acciones de exito y falla de la llamada al WebMethod, esto se da de la forma PageMethods.<nombreWebMethod>(<funcion exito>,<funcion falla>)
4. Se debe establecer la propiedad EnablePageMethods=true para poder exponer los WebMethods de la pagina.
Tarea 03 – Llamando WebServices desde el cliente
1. Crearemos un Ajax-enabled WCF Service CarPictures.svc
2. Se crearan 2 archivos en nuestro sitio web:
3. Antes de proseguir con el ejemplo modificaremos el codigo en CarPictures.designer.cs. A la clase Manufacturer (y opcionalmente a todas) le agregaremos el atributo DataContract
1: [System.Runtime.Serialization.DataContract]
2: [Table(Name="dbo.Manufacturer")]
3: public partial class Manufacturer : INotifyPropertyChanging, INotifyPropertyChanged
4. A su vez le daremos atributo DataMember a las propiedades de la clase
1: //...
2: [System.Runtime.Serialization.DataMember]
3: [Column(Storage="_Name", DbType="VarChar(20) NOT NULL", CanBeNull=false)]
4: public string Name
5: //...
5. Pasaremos a modificar el codigo en CarPicturesService.cs agregando 3 metodos:
1: [OperationContract]
2: public List<Manufacturer> GetManufacturers()
3: {
4: CarPicturesDataContext cp = new CarPicturesDataContext();
5: List<Manufacturer> lstManufacturers =
6: (from m in cp.Manufacturers select m).ToList<Manufacturer>();
7: return lstManufacturers;
8: }
9:
10: [OperationContract]
11: public void InsertManufacturer(Manufacturer m)
12: {
13: if (m != null)
14: {
15: Manufacturer mfr = new Manufacturer();
16: mfr.CountryID = m.CountryID;
17: mfr.Name = m.Name;
18: CarPicturesDataContext cp = new CarPicturesDataContext();
19: cp.Manufacturers.InsertOnSubmit(mfr);
20: cp.SubmitChanges();
21: }
22: }
23:
24: [OperationContract]
25: public List<Country> GetCountries()
26: {
27: CarPicturesDataContext cp = new CarPicturesDataContext();
28: List<Country> lstCountries = (from c in cp.Countries select c).ToList<Country>();
29: return lstCountries;
30: }
6. Ahora volveremos a la pagina ClientMsAjax.cs, agregaremos en ella un HTML Input Text, un HTML Select, un HTML Button, una lista <ul>
1: <input id="txtManufacturerName" type="text" />
2: <select id="selectManufacturerCountry">
3: </select>
4: <input id=" btnAddManufacturers" type="button" value="Registrar Manufacturador" />
5: <br />
6: <ul id="lstManufacturers">
7: </ul>
7. Haremos referencia a nuestro servicio WCF agregando la seccion services en el control ScriptManager.
1: <asp:ScriptManager ID="psm" runat="server" EnablePageMethods="true">
2: <Services>
3: <asp:ServiceReference Path="~/CarPicturesService.svc" />
4: </Services>
5: </asp:ScriptManager>
8. Escribiremos el javascript correspondiente a la lista que hemos creado, funcion bindManufacturers
1: function bindManufacturers() {
2: var service = new CarPicturesService();
3: service.GetManufacturers(getManufacturersSuccess, null, null);
4: }
9. Agregaremos la funcion getManufacturersSuccess
1: function getManufacturersSuccess(results) {
2: var sb = new Sys.StringBuilder();
3: for (i = 0; i < results.length; i++) {
4: var m = results[i];
5: sb.append("<li>" + m.Name + "</li>");
6: }
7: $get("lstManufacturers").innerHTML = sb.toString();
8: }
10. Escribiremos el javascript correspondiente al select que hemos creado, funcion bindCountries
1: function bindCountries () {
2: var service = new CarPicturesService();
3: service.GetCountries(getCountriesSuccess, null, null);
4: }
11. Agregaremos la funcion getCountriesSuccess
1: function getCountriesSuccess(results) {
2: var sb = new Sys.StringBuilder();
3: for (i = 0; i < results.length; i++) {
4: var c = results[i];
5: sb.append("<option value=â€+ c.Id +â€>" + c.Name + "</li>");
6: }
7: $get("selectManufacturerCountry ").innerHTML = sb.toString();
8: }
12. Para el registro de nuevos Manufacturers realizaremos el siguiente codigo:
1: function addManufacturer() {
2: var m = {
3: Name: $get("txtManufacturerName").value,
4: CountryID: $get("selectManufacturerCountry").value
5: };
6: CarPicturesService.InsertManufacturer(m, addManufacturerSuccess, null, null);
7: }
8:
9: function addManufacturerSuccess() {
10: alert('Se registro con exito al nuevo manufacturador');
11: bindManufacturers();
12: }
13. Para terminar en pageLoad registraremos el evento del boton de registro asi como los enlaces a datos de Countries y Manufacturers
1: bindManufacturers();
2: bindCountries();
3: $addHandler($get("btnGetManufacturers"), "click", addManufacturer);
14. Ahora probaremos nuestra pagina:
Analisis de la tarea 03
1. Hemos hecho uso de servicios WCF para realizar operaciones de lado del servidor bajo llamada del cliente. Para ello tambien es necesario registrar el servicio (sea WCF o WebService) en la seccion Services del control ScriptManager
2. Cuando registramos el servicio se crea automaticamente una clase proxy del servicio <nombre_servicio> que permite hacer invocaciones a los metodos que le pertenecen.
3. Para obtener e insertar datos de los objetos es necesario que tengan el atributo de clase DataContract, asi como sus propiedades DataMember.
4. Los datos que se obtienen de un servicio pueden ser manipulado a un estilo de codigo C# en javascript (ver funciones getCountriesSuccess, getManufacturersSuccess)
El codigo lo pueden descargar del siguiente link:
Espero les haya sido de utilidad. Cualquier duda, comentario o sugerencia no duden en escribirlo ^^
Post.End();