Deserializar JSON a un objeto .NET usando Newtonsoft (¿o tal vez LINQ a JSON?)

Resuelto J Benjamin asked hace 13 años • 12 respuestas

Sé que hay algunas publicaciones sobre Newtonsoft, así que espero que esto no sea exactamente una repetición... Estoy intentando convertir los datos JSON devueltos por la API de Kazaa en un buen objeto de algún tipo.

WebClient client = new WebClient();
Stream stream = client.OpenRead("http://api.kazaa.com/api/v1/search.json?q=muse&type=Album");
StreamReader reader = new StreamReader(stream);

List<string> list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(reader.Read().ToString());

foreach (string item in list)
{
    Console.WriteLine(item);
}

//Console.WriteLine(reader.ReadLine());
stream.Close();

Esa línea de JsonConvert es solo la más reciente que estaba probando... No la entiendo del todo y esperaba eliminar algo de juego de pies preguntándoles. Originalmente estaba tratando de convertirlo en un diccionario o algo así... y en realidad, solo necesito incluir un par de valores allí, así que, a juzgar por la documentación, ¿tal vez LINQ to JSON de Newtonsoft podría ser una mejor opción? ¿Pensamientos/Enlaces?

A continuación se muestra un ejemplo de los datos devueltos JSON:

{
  "page": 1,
  "total_pages": 8,
  "total_entries": 74,
  "q": "muse",
  "albums": [
    {
      "name": "Muse",
      "permalink": "Muse",
      "cover_image_url": "http://image.kazaa.com/images/69/01672812 1569/Yaron_Herman_Trio/Muse/Yaron_Herman_Trio-Muse_1.jpg",
      "id": 93098,
      "artist_name": "Yaron Herman Trio"
    },
    {
      "name": "Muse",
      "permalink": "Muse",
      "cover_image_url": "htt p://image.kazaa.com/images/54/888880301154/Candy_Lo/Muse/Candy_Lo-Muse_1.jpg",
      "i d": 102702,
      "artist_name": "\u76e7\u5de7\u97f3"
    },
    {
      "name": "Absolution",
      "permalink": " Absolution",
      "cover_image_url": "http://image.kazaa.com/images/65/093624873365/Mus e/Absolution/Muse-Absolution_1.jpg",
      "id": 48896,
      "artist_name": "Muse"
    },
    {
      "name": "Ab solution",
      "permalink": "Absolution-2",
      "cover_image_url": "http://image.kazaa.com/i mages/20/825646911820/Muse/Absolution/Muse-Absolution_1.jpg",
      "id": 118573,
      "artist _name": "Muse"
    },
    {
      "name": "Black Holes And Revelations",
      "permalink": "Black-Holes-An d-Revelations",
      "cover_image_url": "http://image.kazaa.com/images/66/093624428466/ Muse/Black_Holes_And_Revelations/Muse-Black_Holes_And_Revelations_1.jpg",
      "id": 48813,
      "artist_name": "Muse"
    },
    {
      "name": "Black Holes And Revelations",
      "permalink": "Bla ck-Holes-And-Revelations-2",
      "cover_image_url": "http://image.kazaa.com/images/86/ 825646911486/Muse/Black_Holes_And_Revelations/Muse-Black_Holes_And_Revelations_1 .jpg",
      "id": 118543,
      "artist_name": "Muse"
    },
    {
      "name": "Origin Of Symmetry",
      "permalink": "Origin-Of-Symmetry",
      "cover_image_url": "http://image.kazaa.com/images/29/825646 912629/Muse/Origin_Of_Symmetry/Muse-Origin_Of_Symmetry_1.jpg",
      "id": 120491,
      "artis t_name": "Muse"
    },
    {
      "name": "Showbiz",
      "permalink": "Showbiz",
      "cover_image_url": "http: //image.kazaa.com/images/68/825646182268/Muse/Showbiz/Muse-Showbiz_1.jpg",
      "id": 60444,
      "artist_name": "Muse"
    },
    {
      "name": "Showbiz",
      "permalink": "Showbiz-2",
      "cover_imag e_url": "http://image.kazaa.com/images/50/825646912650/Muse/Showbiz/Muse-Showbiz_ 1.jpg",
      "id": 118545,
      "artist_name": "Muse"
    },
    {
      "name": "The Resistance",
      "permalink": "T he-Resistance",
      "cover_image_url": "http://image.kazaa.com/images/36/825646864836/ Muse/The_Resistance/Muse-The_Resistance_1.jpg",
      "id": 121171,
      "artist_name": "Muse"
    }
  ],
  "per_page": 10
}

Leí un poco más y descubrí que LINQ to JSON de Newtonsoft es exactamente lo que quería... usando WebClient, Stream, StreamReader y Newtonsoft... Puedo presionar Kazaa para obtener datos JSON, extraer una URL, descargar el archivo y hacerlo. ¡Todo en como siete líneas de código! Me encanta.

WebClient client = new WebClient();
Stream stream = client.OpenRead("http://api.kazaa.com/api/v1/search.json?q=muse&type=Album");
StreamReader reader = new StreamReader(stream);

Newtonsoft.Json.Linq.JObject jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());

// Instead of WriteLine, 2 or 3 lines of code here using WebClient to download the file
Console.WriteLine((string)jObject["albums"][0]["cover_image_url"]);
stream.Close();

Esta publicación recibe tantas visitas que pensé que podría ser útil incluir los bits de "uso" que se analizan en los comentarios.

using(var client = new WebClient())
using(var stream = client.OpenRead("http://api.kazaa.com/api/v1/search.json?q=muse&type=Album"))
using (var reader = new StreamReader(stream))
{
    var jObject = Newtonsoft.Json.Linq.JObject.Parse(reader.ReadLine());
    Console.WriteLine((string) jObject["albums"][0]["cover_image_url"]);
}
J Benjamin avatar Jan 20 '11 23:01 J Benjamin
Aceptado

Puede utilizar el dynamictipo C# para facilitar las cosas. Esta técnica también simplifica la refactorización, ya que no depende de hilos mágicos.

JSON

La cadena JSON siguiente es una respuesta simple de una llamada API HTTP y define dos propiedades: Idy Name.

{"Id": 1, "Name": "biofractal"}

C#

Úselo JsonConvert.DeserializeObject<dynamic>()para deserializar esta cadena en un tipo dinámico y luego simplemente acceda a sus propiedades de la forma habitual.

dynamic results = JsonConvert.DeserializeObject<dynamic>(json);
var id = results.Id;
var name= results.Name;

Si especifica el tipo de resultsvariable como dynamic, en lugar de usar la varpalabra clave, entonces los valores de propiedad se deserializarán correctamente, por ejemplo, Ida an inty no a JValue(gracias a GFoley83 por el comentario a continuación).

Nota : El enlace NuGet para el ensamblado de Newtonsoft es http://nuget.org/packages/newtonsoft.json .

Paquete : también puede agregar el paquete con el instalador nuget live, con su proyecto abierto simplemente busque el paquete y luego instálelo , desinstale, actualice , simplemente se agregará a su proyecto en Dependencias/NuGet.

biofractal avatar May 23 '2012 10:05 biofractal

Si solo necesita obtener algunos elementos del objeto JSON, usaría la JObjectclase LINQ to JSON de Json.NET. Por ejemplo:

JToken token = JObject.Parse(stringFullOfJson);

int page = (int)token.SelectToken("page");
int totalPages = (int)token.SelectToken("total_pages");

Me gusta este enfoque porque no es necesario deserializar completamente el objeto JSON. Esto resulta útil con API que a veces pueden sorprenderte con propiedades de objetos faltantes, como Twitter.

Documentación: Serializar y deserializar JSON con Json.NET y LINQ to JSON con Json.NET

arcain avatar Jan 20 '2011 16:01 arcain

Con la dynamicpalabra clave, resulta realmente fácil analizar cualquier objeto de este tipo:

dynamic x = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);
var page = x.page;
var total_pages = x.total_pages
var albums = x.albums;
foreach(var album in albums)
{
    var albumName = album.name;

    // Access album data;
}
Sushant Srivastava avatar Aug 28 '2014 06:08 Sushant Srivastava