sábado, 5 de mayo de 2012

Envíar un JSON bien formado asincrónicamente al servidor sin morir en el intento (ASP.NET MVC + AJAX + JSON)

Bueno, desde que trabajo con ASP.NET MVC se me ha hecho más que recurrente postear un JSON en el servidor de manera asincrónica utilizando la función $.ajax de jQuery. El problema surge cuando se necesita realizar el binding de tu JSON con un objecto complejo creado en C# que puede tener muchos niveles de profundidad.

He visto en internet muchos artículos en donde cada vez que se necesita crear un objeto json lo hacen de esta manera:
var persona = {
nombre: 'Max',
edad: '24'
};
Lo cual es muy útil cuando tienes un objeto sencillo, pero ¿Qué pasa si necesitamos crear un JSON dinámicamente y a demás complejo de muchos niveles? las probabilidades de que el JSON quede mal formado son muy grandes y lo que tambien es muy probable es que pases mucho rato tratando de solucionar este problema. ¿La solución? ... Objetos y Clases en JavaScript :-) Para estos casos es muy conveniente utilizar clases y objetos en javascript, bueno comencemos con un ejemplo: Crearemos entonces algunas clases:
//Definimos nuestras clases.
function Persona(){
   this.Nombre = "";
   this.Apellido = "";  
   this.Edad = ""
   this.Mascotas = new Array();
}

function Mascota(){
   this.Nombre = "";
   this.Tipo = "";
   this.Edad = "";
}

//Creamos una persona 
var persona = new Persona();

persona.Nombre = "Max";
persona.Apellido = "Becerra";
persona.Edad = "24";

//Creamos nuestra primera Mascota
var perrito = new Mascota();

perrito.Nombre = "Pillín";
perrito.Tipo = "Perro";
perrito.Edad = "6";

//Creamos nuestra segunda Mascota

var gatito = new Mascota();

gatito.Nombre = "Tommy";
gatito.Tipo = "Gato";
gatito.Edad = "2";

//Ahora procederemos a asignarle las mascotas a nuestra persona

persona.Mascotas.push(perrito);
persona.Mascotas.push(gatito);

//Bueno el objeto que hemos creado no es tan complejo pero  
//al crearse dinámicamente puede adquirir muchos más niveles
//de los que les hemos dado acá.


A estas alturas debes estar preguntandote ¿Y el JSON?, bueno es aquí donde viene lo mejor, utilizaremos la función JSON.stringify de Javascript que permite pasarle cómo parametro un objeto JavaScript y serializarlo :
var json = JSON.stringify(persona);
Entonces nuestra variable json almacena un JSON pfectamente serializado y de esta manera nos evitamos tener errores de formato. Ahora lo que nos falta es enviarlo al servidor asincrónicamente utilizando AJAX:
$.ajax({
                type: "POST",
                url: url,
                data: json,
                contentType: 'application/json; charset=utf-8',
                success: function (datos) {
                    if (datos) {
                        alert("Funciona :-)");
                    }
                    else {
                        alert("No funciona :-(");
                    }
                }
            });
Es muy importante no olvidar agregar explicitamente el attributo: contentType: 'application/json; charset=utf-8' en la función AJAX ya que si no lo haces estarás enviando un JSON al servidor pero este jamás sabrá que lo que envías es un JSON y esto es esencial para que el controller de ASP.NET MVC pueda realizar el binding adecuado entre el JSON y tu objeto complejo. Hasta la próxima y Happy Coding! :-)

3 comentarios:

  1. Muy buen aporte, una pregunta como seria del lado del servidor para recojer el objeto JSON y crear el objeto?

    ResponderEliminar
    Respuestas
    1. Hola Pit, gracias por comentar editaré el artículo para añadir esa parte, de antemano te puedo contar que al envíar el JSON al servidor ASP.NET MVC realiza un binding de los campos de este objeto con uno que tú tengas creado en el servidor (se debe recibir como parámetro en el "Controller"), la única condición que tienes es que los campos de tu objeto en javascript y tu objeto en C# se llamen de la misma manera y listo, tienes un objeto en el servidor que se ha llenado con un JSON desde el cliente :), de todas maneras cómo te decía antes actualizaré la entrada para agregar esa parte.

      Saludos

      Eliminar
  2. Muy bien explicado gracias, pero ¿Como recibes ese json en la función webmethod en c#?

    ResponderEliminar