Menú de navegaciónMenú
Categorías

La mejor forma de Aprender Programación online y en español www.campusmvp.es

?id=64652fb8-d482-42fe-bdb1-5521eac8fb0d

Cómo usar JSON en .NET fácilmente con C#

Icono de advertencia ATENCIÓN: este contenido tiene más de 2 años de antigüedad y, debido a su temática, podría contener información desactualizada o inexacta en la actualidad.

IMPORTANTE: este post es muy antiguo y en la actualidad .NET tiene integradas sus propias clases de manejo de JSON que te permiten hacer la conversión de una clase a JSON y viceversa de manera sencilla, con mayor rendimiento y sin depender de paquetes externos. Te recomendamos que leas mejor este artículo: Cómo manejar JSON en .NET con System.Text.Json.

El formato JSON se ha convertido en los últimos años en uno de los más utilizados por los servicios web para proporcionar información a los desarrolladores. En este artículo te enseñamos cómo podemos utilizarlo en C# de manera sencilla.

JSON vs XML

Algunas ventajas por las cuales se ha popularizado mucho JSON frente a su principal formato competidor hasta el momento (XML) son:

  • El uso de una sintaxis más reducida, lo que implica intercambio de datos más pequeños
  • La facilidad para poder ser leído por una persona
  • La sencillez de su generación (y uso) utilizando tecnologías web

Buscando un proveedor de datos

Para intentar que el artículo te resulte lo más útil posible si necesitas conectar tu aplicación .NET a una API que devuelva JSON, vamos a realizar un ejemplo realista paso a paso.

Para ello hemos seleccionado la API Weathers como base para el ejemplo que veremos a continuación. Esta API, como su propio nombre indica, nos va a proporcionar información meteorológica de la ciudad que le indiquemos (Madrid en nuestro ejemplo).

El código para llamar a la API consiste en realizar una petición GET a la URL http://weathers.co/api.php?city=Madrid. Como resultado nos devuelve la siguiente información en formato JSON (en la figura la vemos desplegada):

Resultado de la API del tiempo mostrando la información de la ciudad de Madrid

Como podemos ver en la imagen anterior, nos informa de cuál es la temperatura en Madrid, la humedad y otros datos climatológicos.

Creando la clase Meteorología

Para tratar en C# el resultado anterior, estaremos de acuerdo en que lo mejor sería almacenar cada uno de los datos como una propiedad en una clase. En este caso he decidido llamar a la clase Meteorologia, pero esta clase no la vamos a crear nosotros a mano, sino que se creará de manera automática siguiendo estos pasos:

  1. Vamos a realizar una petición a la API, por ejemplo desde el navegador, para copiar la respuesta que nos da.
  2. Vamos a entrar en json2csharp y vamos a copiar la respuesta de la API.
  3. Le damos al botón de generar, para que nos cree la clase o clases necesarias para mapear cada uno de los campos del JSON, en propiedades de las clases.
  4. Copiamos el código de las clases resultantes en Visual Studio, teniendo en cuenta que renombraremos la clase RootObject, con el nombre que nosotros queramos usar, en este caso Meteorologia.
  5. Yo normalmente renombro las propiedades para que tengan la primera letra en mayúsculas, pero esto es una cuestión de estilo y no es obligatorio.

El código resultante de nuestras clases será, en este caso, el siguiente:

public class Meteorologia
{
    public string ApiVersion { get; set; }
    public Data Data { get; set; }
}

public class Data
{
    public string Location { get; set; }
    public string Temperature { get; set; }
    public string Skytext { get; set; }
    public string Humidity { get; set; }
    public string Wind { get; set; }
    public string Date { get; set; }
    public string Day { get; set; }
}

Realizando la petición y el parseo del JSON

El formato JSON está soportado de forma nativa por C#. Sin embargo, en este caso vamos a utilizar una biblioteca externa denominada JSON.Net. Ésta ofrece muchas ventajas frente a la nativa, como por ejemplo:

  • Es mucho más rápida en el procesado de ficheros JSON. Tanto es así que la propia Microsoft la utiliza en sus desarrollos.
  • Es muy sencilla de usar.
  • Permite serializar y deserializar cualquier objeto de .Net desde JSON y viceversa.

Para añadir esta biblioteca a nuestro proyecto, lo podemos hacer bajando el archivo desde su página o bien usando el administrador de paquetes de NuGet:

Instalando con el gestor de paquetes NuGet la biblioteca JSON.net

Finalmente realizamos la petición GET para recibir la información en JSON y usamos el método JsonConvert.DeserializeObject<>() para deserializar el JSON en nuestra clase, como se ve a continuación:

Meteorologia meteorologia;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"http://weathers.co/api.php?city=Madrid");
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
    var json = reader.ReadToEnd();
    meteorologia = JsonConvert.DeserializeObject<Meteorologia>(json);
}
Console.WriteLine("La temperatura en Madrid es: " + meteorologia.Data.Temperature);

Espero que este artículo te parezca interesante y te ayude a incorporar servicios web que utilizan JSON en tus desarrollos.

Fecha de publicación:
Jorge Durán

Jorge es Ingeniero Informático por la Universidad de Salamanca. Es un entusiasta de la tecnología desde los 10 años, y ha escrito decenas de artículos en blogs relacionados con la informática. Lo puedes seguir en sus blogs Lenguaje de programación y Somos Binarios.

Ver todos los posts de Jorge Durán
Archivado en: Trucos

Boletín campusMVP.es

Solo cosas útiles. Una vez al mes.

🚀 Únete a miles de desarrolladores

DATE DE ALTA

x No me interesa | x Ya soy suscriptor

La mejor formación online para desarrolladores como tú

Comentarios (20) -

Muchas gracias me salvaste la vida.... Saludos

Responder

Alberto García
Alberto García

Copia en el portapapeles el json, te vas a Visual Studio, menú  edit y pulsas sobre paste special dentro de una clase, te genera automáticamente el mapeo del json sin necesidad de salir del propio entorno
Saludos

Responder

Jose Herreros
Jose Herreros

Excelente tip para Visual Studio, muchas gracias

Responder

Parece que el servicio ya no está disponible.

Responder

Hola Alfredo:

En efecto, parece que el servicio del tiempo usado para el ejemplo está caído ahora mismo o ha desaparecido. Una pena. No obstante era solo un ejemplo concreto por ilustrar los conceptos del artículo, que sigue siendo válido. Gracias por avisar.

Saludos.

Responder

Una consulta porque usas var si estas en .NET C#?? a mi me tira error eso!

Responder

Hola Carlos:

var es una palabra normal y corriente de C# desde hace muchos años. Significa que le dejas al compilador determinar el tipo correcto de la variable sin necesidad de que se lo indiques tú. Si te da error es porque debes de estar compilando para una versión de .NET antiquísima-

Puedes ver la documentación sobre var aquí:

docs.microsoft.com/.../var

Saludos

Responder

Esteban Peralta Nuñez
Esteban Peralta Nuñez

muchas gracias, muy facil entender como funciona y como se trabaja, eres genial, gracias.

Responder

Gracias por la explicación, pero tengo una duda. ¿Se puede leer un JSON sin una clase en particular porque puede variar de etiqueta y contenido?

Responder

Hola Andrés:

Sí, es muy fácil de conseguir gracias a las maravillas de la palabra clave dynamic de C#.

Bastaría con hacer algo como esto (usando el objeto JObject de LINQ to JSON de la biblioteca que se comenta en el artículo):

dynamic o = JObject.Parse("Cadena de texto con el JSON que queremos parsear");

y luego para acceder a cualquier propiedad bastaría con usar su nombre directamente. Por ejemplo:

o.Data.Temperatura

Saludos.

Responder

Magnífico artículo. Me diste la solución. Millones de gracias.

Responder

Excelente, es lo que hacia yo, pero el problema es cuando intentas enviar una lista de lista de listas de objetos por post, tuve que hacer el string a mano con codigo en vez de usar el iCollection

Responder

cesar cueto
cesar cueto

en https no funciona json

Responder

Paco Atónito
Paco Atónito

¯\_(ツ)_/¯ ¿¿Wtf??

Responder

José Manuel Alarcón
José Manuel Alarcón

¿Qué quiere decir eso? Lo explicado en el post sirve conHTTP y HTTPS. Quizá el sitio al que estás accediendo tiene un certificado no válido o que sólo es valido localmente. En ese caso puedes solucionarlo aceptando el certificado aunque no sea válido (https://stackoverflow.com/a/561242). Pero en caso contrario, funciona.

Si no es esto, or favor, explica exactamente qué te pasa, incluso danos un URL de ejemplo, y a ver si podemos ayudarte.

Saludos.

Responder

Hola que tal? he probado tu solucion pero me arroja un error

Tengo una clase donde he creado lo siguiente:

public class DataPrincipal
    {
        public Data Data { get; set; }
    }

public class Data
    {
        public string validado { get; set; }
    }

public static string ProbandoJson (string result)
        {
            DataPrincipal dataPrincipal;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"http://URL/api/consultarlicencia/"+result);
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            using (Stream stream = response.GetResponseStream())
            using (StreamReader reader = new StreamReader(stream))
            {
                var json = reader.ReadToEnd();
                dataPrincipal= JsonConvert.DeserializeObject<DataPrincipal>(json);
            }

            string result = dataPrincipal.Data.validado;
            return result;
        }


Y me dice: "System.NullReferenceException: 'Referencia a objeto no establecida como instancia de un objeto.'

ActualizarMapas.Clases.DataLicencia.Data.get devolvió null."

Cuando estoy Debugeando puedo observar que "var json" si tiene el valor y que lo esta consultando. Donde esta la metida de pata?

Responder

Consulta los campos de la clase a devolver siempre tienen que ser todos string? Y otra consulta como recibo por parámetro una lista de artículos por ejemplo en json llamando a una api rest vb.net

Responder

Hola Jose:

Los campos pueden ser del tipo que quieras, incluso de tipos complejos. Y esto responde a tu otra pregunta: si el servicio REST (da igual en qué lenguaje de servidor esté desarrollado) devuelve una lista de artículos, al deserializar el JSON los puedes obtener en forma de una lista de objetos del tipo que necesites, algo así:

List<Producto> productos = JsonConvert.DeserializeObject<List<Producto>>(json);

En la documentación de Json.NET puedes ver cómo se hace cualquier cosa de estas:

www.newtonsoft.com/json/help/html/Introduction.htm

y verás que es muy sencillo.

Saludos

Responder

Test test;
            var json = "";
            List <Test> lTest = new List<Test>();
            HttpWebRequest petition = (HttpWebRequest)WebRequest.Create(@"https://jsonplaceholder.typicode.com/posts";);
            using (HttpWebResponse response = (HttpWebResponse)petition.GetResponse())
            using (Stream stream = response.GetResponseStream())
            using (StreamReader reader = new StreamReader(stream))  
            {
                json = reader.ReadToEnd();
                test = JsonConvert.DeserializeObject<Test>(json);
            }
            Console.WriteLine("La primera ID es: " + test.id);

Me da error al deserialzar el objeto  " test = JsonConvert.DeserializeObject<Test>(json);" en esa linea me da unleash exception.

Unhandled exception. Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'EmpesaWilaon.Object.Test' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.

Responder

Me encontre con el mismo problema y lo solucione usando JsonConvert.DeserializeObject<List<Root>>(json);

pego el codigo que soy muy malo explicandome.... este es mi ejemplo

private void button1_Click(object sender, EventArgs e)
        {


            List<Root> minerstatData = new List<Root>();

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"https://api.minerstat.com/v2/coins";);
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            using (Stream stream = response.GetResponseStream())
            using (StreamReader reader = new StreamReader(stream))
            {
                var json = reader.ReadToEnd();
                minerstatData = JsonConvert.DeserializeObject<List<Root>>(json);

            }

        }
    }


    public class Root
    {
        public string id { get; set; }
        public string coin { get; set; }
        public string name { get; set; }
        public string type { get; set; }
        public string algorithm { get; set; }
        public double network_hashrate { get; set; }
        public object difficulty { get; set; }
        public double reward { get; set; }
        public string reward_unit { get; set; }
        public double reward_block { get; set; }
        public double price { get; set; }
        public double volume { get; set; }
        public int updated { get; set; }
    }


Responder

Agregar comentario

Los datos anteriores se utilizarán exclusivamente para permitirte hacer el comentario y, si lo seleccionas, notificarte de nuevos comentarios en este artículo, pero no se procesarán ni se utilizarán para ningún otro propósito. Lee nuestra política de privacidad.