miércoles, 15 de febrero de 2012

Hey, logre instalar blogger en mi galaxy s

Vamos a ver si asi me animo y empiezo a alimentar mi blog


viernes, 18 de febrero de 2011

JQuery DataTables plug-in with Asp Mvc and Linq

I recently came across with the great DataTables plug-in for Jquery. Using this plug-in with client data is pretty straightforward, but when you face tables with a lot of data you have to transfer the search, paging and sorting function to the server. There are some good scripts for different server side technology's at Data tables site, but none that uses Asp Mvc, and most of this scripts have to be reimplemented for every table and data combination you have on your site. 


Since we always want to reuse as much code as possible i wrote a set of class to use with DataTables that can be reuse with any table on your database.


You can find all my code at http://code.google.com/p/datatables-asp-mvc/downloads/list with comments. I removed the comments on this post for space.


Before we start
For this project we need the Linq Dynamic library that can be found on the VS 2008 Samples download page.


The library is actually a single file you can include in your project, direct link to the library is here:
C# Dynamic Query Library (included in the \LinqSamples\DynamicQuery directory)


To read more about this library check ScottGu's blog

We can put the Dynamic library in our Models folder





For this example I'm going to use the standard DataTables example schema

I'm using Asp Mvc3 for this example, but it should work on all the previous versions.

First we need to obtain the parameters send by DataTables from the client on our controller, for this we create a model to store the parameters and save it in our Models folder.



For this example i save most of the code in the Models folder inside the MVC Project, but in a real project most of this should be in different libraries.


-------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
namespace DataTables.Models
{    
    public class DataTablesParam
    {
        public int iDisplayStart { getset; }
        public int iDisplayLength { getset; }
        public int iColumns { getset; }
        public string sSearch { getset; }
        public bool bEscapeRegex { getset; }
        public int iSortingCols { getset; }
        public string sEcho { getset; }
        public List<bool> bSortable { getset; }
        public List<bool> bSearchable { getset; }
        public List<string> sSearchColumns { getset; }
        public List<int> iSortCol { getset; }
        public List<string> sSortDir { getset; }
        public List<bool> bEscapeRegexColumns { getset; }
 
        public DataTablesParam()
        {
            bSortable = new List<bool>();
            bSearchable = new List<bool>();
            sSearchColumns = new List<string>();
            iSortCol = new List<int>();
            sSortDir = new List<string>();
            bEscapeRegexColumns = new List<bool>();
        }
    }
}
------
Now we create our controller and action to handle the Ajax request:


---------
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using DataTables.Models;
 namespace DataTables.Controllers
{
    public class ajaxController : Controller
    {         
        public ContentResult GetAjax(DataTablesParam dataTableParam)
        {            
            return null;  // we still have some work to do before returning anything!   
        }
    }
}
-------
Since DataTables send some parameters in a format not recognize by the default Model Binder we have to construct a custom one.


-------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace DataTables.Models
{    
    public class DataTablesModelBinding : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            DataTablesParam obj = new DataTablesParam();
            var request = controllerContext.HttpContext.Request.Params;
            
            obj.iDisplayStart = Convert.ToInt32(request["iDisplayStart"]);
            obj.iDisplayLength = Convert.ToInt32(request["iDisplayLength"]);
            obj.iColumns = Convert.ToInt32(request["iColumns"]);
            obj.sSearch = request["sSearch"];
            obj.bEscapeRegex = Convert.ToBoolean(request["bEscapeRegex"]);
            obj.iSortingCols = Convert.ToInt32(request["iSortingCols"]);
            obj.sEcho = request["sEcho"];
            
            for (int i = 0; i < obj.iColumns; i++)
            {
                obj.bSortable.Add(Convert.ToBoolean(request["bSortable_" + i]));
                obj.bSearchable.Add(Convert.ToBoolean(request["bSearchable_" + i]));
                obj.sSearchColumns.Add(request["sSearch_" + i]);
                obj.bEscapeRegexColumns.Add(Convert.ToBoolean(request["bEscapeRegex_" + i]));
                obj.iSortCol.Add(Convert.ToInt32(request["iSortCol_" + i]));
                obj.sSortDir.Add(request["sSortDir_" + i]);
            }
            return obj;            
        }
    }
}
------
And add the model binder in global.asax:




------

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
 
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);    
    ModelBinders.Binders.Add(typeof(DataTablesParam), new DataTablesModelBinding());
}
-----
Now we create two class to query the databases based on the DataTables parameters.
 The first class receive a IQueryable with the data you want to apply the DataTables parameters, this class should be created once in the whole project and then call it for each DataTable in the site. 
To  perform the sorting and search query on the database, we need to know the name of the columns we are working on. This is where Linq dynamics kicks in, the column names are passed to the   function in a string array, saved in the same order we render then on the site, then use this information to dynamically construct the query on a string. Additional to this, the function receive the type of data each column is storing, so we can threat the columns different on the search function. For example, in this case if the column is a number i use the function StartsWith while if it's a string i use Contains. This can be changed to any behavior you want.


-----
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
using System.Linq.Dynamic;
namespace DataTables.Models
{
 
    public enum DataType
    {
        tInt,
        tString,
        tnone
    }
 
    public class DataTableFilter
    {        
        public IQueryable FilterPagingSortingSearch(DataTablesParam DTParams, IQueryable data, out int totalRecordsDisplay,
            string[] columnNames, DataType[] types)
        {
            
            if (!String.IsNullOrEmpty(DTParams.sSearch))
            {                
                string searchString = "";
                bool first = true;
                for (int i = 0; i < DTParams.iColumns; i++)
                {
                    if (DTParams.bSearchable[i]) 
                    {                       
                        string columnName = columnNames[i];      
 
                        if (!first)
                            searchString += " or ";
                        else
                            first = false;
                       
                        if (types[i] == DataType.tInt)
                        {
                            searchString += columnName + ".ToString().StartsWith(\"" + DTParams.sSearch + "\")";
                        }                       
                        else
                        {
                            searchString += columnName + ".Contains(\"" + DTParams.sSearch + "\")";
                        }
                    }
                }                
                data = data.Where(searchString);
            }
            string sortString = "";
            for (int i = 0; i < DTParams.iSortingCols; i++) 
            {                
                int columnNumber = DTParams.iSortCol[i];
                string columnName = columnNames[columnNumber];               
                string sortDir = DTParams.sSortDir[i];
                if (i != 0)
                    sortString += ", ";
                sortString += columnName + " " + sortDir;
            } 
            
            totalRecordsDisplay = data.Count(); 
            
            data = data.OrderBy(sortString);            
            data = data.Skip(DTParams.iDisplayStart).Take(DTParams.iDisplayLength);
 
            return data;
        }
    }
}
-----
Finally the BLL class that gets called from the controller. This class first query the data you want to filter, and then calls the previous function. 

This is the class that should be created for each different table on the site, where we make the query and set the columns we are using.



------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
namespace DataTables.Models
{
    public class AjaxBLL
    {
        public string ListAjax(DataTablesParam param)
        {                 
            string[] columnNames = { "engine""browser""platform""version""grade" };

            DataType[] types = { DataType.tString, DataType.tString, DataType.tString, DataType.tInt, DataType.tString };

            DataTables.Models.DataClasses1DataContext db =
                new DataTables.Models.DataClasses1DataContext(System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString); 

            int totalRecords = db.ajaxes.Count(u => u.id < 100);

            var data = db.ajaxes.Where(u=>u.id < 100);
 
            int totalRecordsDisplay;
 
            DataTableFilter filters = new DataTableFilter();
 
            
            data = filters.FilterPagingSortingSearch(param, data, out totalRecordsDisplay, columnNames, types) as IQueryable<DataTables.Models.ajax>;
            var listData = data.ToList(); 
            
            string jsonResponse;
            jsonResponse = "{\"iTotalRecords\":" + totalRecords + ",\"iTotalDisplayRecords\":" + totalRecordsDisplay + ",\"sEcho\":" + param.sEcho +
                ",\"aaData\":["; 
           
            for (int i = 0; i < listData.Count; ++i)
            {
                var ajx = listData[i];
                if (i > 0)
                    jsonResponse += ",";
                jsonResponse += "[\"" + ajx.engine + "\",\"" + ajx.browser + "\",\"" + ajx.platform + "\",\"" + ajx.version + "\",\"" + ajx.grade + "\"]";
            }
            jsonResponse += "]}";
            return jsonResponse;
        }
    }
}
-----
For the last example i use Linq to Sql to query the data, getting the connection string from web.config, inside the configuration tag , but you can use any connection that implements IQueryable.

<connectionStrings>
<add name="MyConnectionString" connectionString="Data Source=127.0.0.1;Initial Catalog=ajaxExample;Persist Security Info=True;User ID=sa;Password=123456;" providerName="System.Data.SqlClient" />  
connectionStrings>

lunes, 17 de enero de 2011

Usando Json para aplicaciones ricas en Ajax (parte 1)

Cada vez es mas común las páginas web ricas en Ajax, donde gran parte de las funcionalidades de la página se desarrollan sin tener que realizar refresh completos de la misma, en su lugar se utiliza Javascript para comunicarnos con el servidor vía Ajax, por ejemplo tenemos gmail o google docs.


Tradicionalmente la comunicación entre el servidor y el cliente se ha manejado de dos maneras: el servidor envía el html completo que se quiere dibujar en el browser, o el servidor envía datos en formato XML que luego es interpretado por el cliente utilizando javascript, generando el HTML a dibujar.


Sin embargo en años reciente se ha desarrollado un estándar para intercambio de datos: Json. Este estándar se caracteriza por ser liviano, fácil de leer y requiere pocos caracteres para representar datos, comparado con XML.


Esto se traslada en una gran ventaja para su uso en aplicaciones con ajax, ya que  reduce en gran medida la cantidad de datos que se envían entre el servidor y el cliente, lo cual siempre es algo deseado en el envió de datos en la internet. 


A esto se le suma que los motores de javascript actuales poseen soporte nativo para leer datos Json, a diferencia de tener que parsear un XML, lo que es un trabajo mucho mas tedioso y lento, que ademas puede requerir datos adicionales como archivo XSD que aumenta aun mas la carga de datos.


Un objeto Json es una colección nombre/valor, que puede almacenar 5 tipos de datos: string, número, objeto (json), array, booleano. 


Los objetos Json se declaran inicialmente con una llave abriendo '{' y se finalizan con una llave cerrando '}'. Dentro de estás llaves declaramos los pares nombre/valor, colocando primero el nombre seguido de dos puntos ':' seguido de su valor. Cada par nombre/valor es separado por una coma ','.


Por ejemplo, supongamos que queremos definir un objecto de una persona en javascript, con una lista de números telefónicos, y datos de su habitación:


var persona = { nombre: 'pedro', apellido: ' perez', numerosTelefonicos: [3712424, 4569874], habitacion: { ciudad: 'caracas', estado: 'Miranda'} }
La navegación en Javascript es igual de sencilla, simplemente referenciamos lo que deseamos obtener:
var nombre = persona.nombre;
var segundoNumero = persona.numerosTelefonicos[1];
var ciudadHabitacion = persona.habitacion.ciudad;
Para mas información acerca de esté estadar puedes visitar su página oficial http://www.json.org/ o el articulo en wikipedia http://en.wikipedia.org/wiki/JSON

En cuanto al servidor, retornar esté tipo de objetos es bastante sencillo, simplemente colocamos en la respuesta la cadena con el objeto JSon, como por ejemplo:
 { nombre: 'pedro', apellido: ' perez', numerosTelefonicos: [3712424, 4569874], habitacion: { ciudad: 'caracas', estado: 'Miranda'} }
y el mime type application/json

En caso de que uses asp mvc framework puedes utilizar la funcion Json, que retorna un ActionResult, con un objeto anonimo:

public ActionResult ejemplo()
{
     return Json(new { nombre = "Jose" });
}
Incluso puedes retornar un arreglo de objetos:

public ActionResult ejemplo()
{
  List<Persona> personas = new List<Persona>();
  personas.Add(new Persona { nombre = "David" });
  personas.Add(new Persona { nombre = "Andres" });
  return Json(personas);
}

Esto retornara lo siguiente al cliente:
[{nombre:'David'},{nombre:'Andres'}]
En la próxima parte de este articulo veremos como facilitar el manejo de estos datos y generar Html en el cliente con la ayuda del Plugin de JQuery para templates http://api.jquery.com/jquery.tmpl/

viernes, 30 de julio de 2010

Programación acordeón con JQuery

En mi ultimo proyecto desarrollado, para el hotel lagunamar en la isla de margarita; se presento una página interna donde se requería un acordeón para mostrar información. 




Aunque existen varios Plugins  para realizar acordeones como http://docs.jquery.com/UI/Accordion, el código lo desarrolle por mi cuenta ya que es bastante sencillo y un buen proceso de aprendizaje.

Primero veamos el Html completo para un acordeón de 3 tabs:

<div id="acordeon">    

   <div class="headerTabApagado headerTab">

          <div class="verdana14 bold labelApagado labelHeader">

                  Titulo 1

          </div>

          <div class="flechaTab flechaTabAbajo"></div>

   </div>

   <div class="contAcordion verdana12 darkgray">     

           <div style="float:left;width:300px;">

               <img width="256px" height="170px" alt="lagunamar" src="img.jpg" />

           </div>

           <div style="float:left;width:326px;">

                     Et lorem tristique amet integer tristique et integer et, vel amet, porta urna montes sit ut! Ultrices?

           </div> 

   </div>


   <div class="headerTabApagado headerTab">

          <div class="verdana14 bold labelApagado labelHeader">

                  Titulo 1

          </div>

          <div class="flechaTab flechaTabAbajo"></div>

   </div>

   <div class="contAcordion verdana12 darkgray">     

           <div style="float:left;width:300px;">

               <img width="256px" height="170px" alt="lagunamar" src="img.jpg" />

           </div>

           <div style="float:left;width:326px;">

                     pellentesque, purus, amet elementum pid ultrices phasellus! Ultrices amet nu

           </div> 

   </div>   

   <div class="headerTabApagado headerTab">

          <div class="verdana14 bold labelApagado labelHeader">

                  Titulo 1

          </div>

          <div class="flechaTab flechaTabAbajo"></div>

   </div>

   <div class="contAcordion verdana12 darkgray">      

           <div style="float:left;width:300px;">

               <img width="256px" height="170px" alt="lagunamar" src="img.jpg" />

           </div>

           <div style="float:left;width:326px;">

                     Velit enim habitasse duis turpis turpis massa sit cursus e

           </div> 

   </div>

</div>

Simplificando tenemos el código de cada Tab:

<div class="headerTabApagado headerTab">

     <div class="verdana14 bold labelApagado labelHeader">

             Titulo del tab

     </div>

     <div class="flechaTab flechaTabAbajo">

     </div>

</div>

<div class="contAcordion verdana12 darkgray">      

   Contenido del Tab

</div>

Donde tenemos el código del Titulo, área que esta siempre visible:


<div class="headerTabApagado headerTab">

    <div class="verdana14 bold labelApagado labelHeader">

          Título del tab</div>

   <div class="flechaTab flechaTabAbajo">

   </div>

</div>




El contenedor del tab posee dos clases CSS, headerTab que define el estilo general de los tabs:


  .headerTab

  {

      width: 658px;

      height: 42px;

      margin-left: 34px;

      position: relative;

      margin-top: 10px;

      cursor: pointer;

      float: left;

  }
y la clase headerTabApagado, que define el estilo de los tabs que se encuentran cerrados:


  .headerTabApagado

  {

      background-image: url(../Img/FondoGrisAcordeon.png);

      border: 2px solid #8d8d8d;

  }
Dentro de este div tenemos dos contenedores, uno que define el título con las clases CSS labelHeader y labelApagado, que definen los estilos de los títulos en general y de los tabs cerrados respectivamente:







  .labelHeader

  {

      position: absolute;

      top: 12px;

      left: 12px;

  }
   
  .labelApagado

  {

      color: #333333;

  }
Luego tenemos un div con la flecha de la derecha, igualmente con dos clases que representan el estilo general de las flechas, y el especifico de las flechas de los tabs cerrados, flechaTab y flechaTabApagado:





  .flechaTab

  {

      width: 28px;

      height: 28px;

      position: absolute;

      left: 612px;

      top: 7px;

  }   

  .flechaTabAbajo

  {

      background-image: url(../Img/flecha1.png);

  }

Finalmente tenemos el contenido de los Tabs:


  <div class="contAcordion">

      Contenido

  </div>

Ahora la parte mas interesante, el código JavaScript para realizar el efecto:


  $(function () {

              $('.headerTabApagado').click(prender);

          });

   

          function apagar() {

           $(this).removeClass('headerTabPrendido').addClass('headerTabApagado');

           $(this).next('.contAcordion').slideUp();

           $(this).children('.labelHeader').removeClass('labelPrendido').addClass('labelApagado');


           $(this).children('.flechaTabArriba').removeClass('flechaTabArriba').addClass('flechaTabAbajo');

           $(this).unbind('click');

           $(this).click(prender);

       }

       function prender() {

           apagarByNombre($('.headerTabPrendido'));

           $(this).removeClass('headerTabApagado').addClass('headerTabPrendido');

           $(this).next('.contAcordion').slideDown();

           $(this).children('.labelHeader').removeClass('labelApagado').addClass('labelPrendido');

           $(this).children('.flechaTabAbajo').removeClass('flechaTabAbajo').addClass('flechaTabArriba');

           $(this).unbind('click');

           $(this).click(apagar);

       }

       function apagarByNombre(nombre) {

         $(nombre).removeClass('headerTabPrendido').addClass('headerTabApagado');

         $(nombre).next('.contAcordion').slideUp();

         $(nombre).children('.labelHeader').removeClass('labelPrendido').addClass('labelApagado');

         $(nombre).children('.flechaTabArriba').removeClass('flechaTabArriba').addClass('flechaTabAbajo');

         $(nombre).unbind('click');

         $(nombre).click(prender);

     }

En las primeras 3 líneas agregamos la funcionalidad de prender un tab al momento de hacer click sobre el.


La función prender primero se encarga de cerrar el tab que se encuentre abierto previamente, eso lo realiza llamando a apagarByNombre. Luego remueve y agrega estilos Css para cambiar el estilo del tab (de gris a morado). Después utiliza la animación SlideDown para mostrar el contenido del tab. Finalmente remueve la función que tiene asociado actualmente al evento click (el de abrir tab) con $(this).unbind('click'); y le agrega la funcionalidad de cerrar el tab al evento click, $(this).click(apagar);.

Las funciones de apagar actúan de manera similar, intercambian las clases CSS para modificar el aspecto visual, luego llaman a la funcion slideUp() para ocultar el contenido del tab, y finalmente modifican la funcionalidad del evento click sobre ese tab con $(nombre).unbind('click'); y $(nombre).click(prender);



Al momento de escribir el tutorial la página aun no se encuentra al aire, pero pueden observar una vista previa del funcionamiento de los tabs en http://legendsoft.com.ve/Lagunamar/FAQ







martes, 1 de junio de 2010

#webve encuentro de twitteros del area web y tecnología en Caracas.

Mi amigo Oswaldo de http://www.silverexe.com esta promoviendo una iniciativa muy interesante para un encuentro en caracas para los amantes de la tecnología y el área web totalmente gratis.

Para anotarte a este encuentro simplemente coloca el siguiente mensaje en el twitter "Voy al #webve"

Para mayor informacion visita http://www.silverexe.com/Blog.aspx/Post/4/#webve-encuentro-de-twitteros-del-area-web-y-tecnologia-en-Caracas



martes, 18 de mayo de 2010

Nueva forma en Asp.Net 4 de realizar encoding de datos en paginas asp: <%: %>

Anteriormente hablamos de los ataques XSS y como es uno de los ataques mas comunes y eficientes al momento de atacar una pagina web.
Estos ataques consisten en inyectar código no deseado en una pagina web que luego puede ser ejecutado por otro usuario. Por ejemplo si entro a un foro que tenga poca seguridad, y creo un post nuevo con el siguiente codigo:



<script type="text/javascript"> alert('esto es un aviso no deseado')</script>

las personas que entren en este post les saldra un PopUp con el mensaje, a pesar que esto no fue programado por los creadores del foro.

Para solucionar esto se utiliza el Html encoding, esto es, traducir caracteres especiales de html a códigos los cuales al ser leidos por el explorador este los interpreta como texto, en lugar de interpretarlos como código html.

Por ejemplo, en lugar de escribir < script > alert(); < /script > se utilizan los códigos de los caracteres especiales: 




&lt; script &gt; alert(); &lt; &rasl; script &gt;
.  Este código sera interpretado y traducido al texto original por el explorador, en lugar de ejecutarlo como código de javascript. 


La versión de Asp Mvc para c# 3.5 incluye un helper de html que realizaba encoding de cualquier string, el cual se utiliza usualmente en las páginas Asp de la iguiente manera: 

<%= Html.Encode("string") %>



En c# 4.0 para comodidad del programador se ha introducido una nueva manera mas sencilla de realizar encoding, esto es colocando nuestro código c# entre los caracteres

<%: %>
 . Esto funciona de igual manera que 

<%= %>
 , con la diferencia que el string que retorna viene con los caracteres de encoding.