Deserialización de JSON to.NET objeto usando Newtonsoft (o LINQ a JSON tal vez?)


Sé que hay algunas publicaciones sobre Newtonsoft, así que espero que esto no sea exactamente una repetición...Estoy tratando de convertir los datos JSON devueltos por la API de Kazaa en un objeto agradable 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 JsonConvert es solo la más reciente que estaba intentando...No lo estoy entendiendo y esperaba eliminar el juego de pies preguntándoos a vosotros. Originalmente estaba tratando de convertirlo en un diccionario o algo así...y en realidad, solo necesito enganchar un par de valores allí para a juzgar por la documentación, tal vez LINQ a JSON de Newtonsoft podría ser una mejor opción? Pensamientos/Links?

Aquí hay un ejemplo de los datos de retorno 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
}

Hice algunas lecturas más y encontré que LINQ to JSON de Newtonsoft es exactamente lo que quería...usando WebClient, Stream, StreamReader y Newtonsoft...Puedo golpear Kazaa para los 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();

Este post recibe muchos éxitos Pensé que podría ser útil incluir los bits de "uso" que se discuten 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"]);
}
Author: Tim Sylvester, 2011-01-20

11 answers

Si solo necesita obtener algunos elementos del objeto JSON, usaría Json.NET ' s LINQ to JSON JObject class. 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 es útil con las 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

 230
Author: arcain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-16 12:14:16

Puede usar el tipo C# dynamic para hacer las cosas más fáciles. Esta técnica también hace que el re-factoring sea más simple, ya que no se basa en cuerdas mágicas.

JSON

La siguiente cadena JSON es una respuesta simple de una llamada a la API HTTP, y define dos propiedades: Id y Name.

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

C#

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

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

Si se especifica la escriba la variable results como dynamic, en lugar de usar la palabra clave var, entonces los valores de la propiedad se deserializarán correctamente, por ejemplo, Id a un int y no a un 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 .

 236
Author: biofractal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-22 22:57:13

Con la palabra clave dynamic, se vuelve muy 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;
}
 32
Author: Sushant Srivastava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-16 12:17:42

Corrígeme si me equivoco, pero el ejemplo anterior, creo, está ligeramente fuera de sincronía con la última versión de James Newton Json.NET biblioteca.

var o = JObject.Parse(stringFullOfJson);
var page = (int)o["page"];
var totalPages = (int)o["total_pages"];
 21
Author: Rick Leitch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-20 17:54:54

Deserializar y obtener el valor (cuando la colección es dinámica):

// First serializing
dynamic collection = new { stud = stud_datatable }; // The stud_datable is the list or data table
string jsonString = JsonConvert.SerializeObject(collection);


// Second Deserializing
dynamic StudList = JsonConvert.DeserializeObject(jsonString);

var stud = StudList.stud;
foreach (var detail in stud)
{
    var Address = detail["stud_address"]; // Access Address data;
}
 10
Author: Arun Prasad E S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-15 01:58:33

Además, si solo estás buscando un valor específico anidado dentro del contenido JSON, puedes hacer algo así:

yourJObject.GetValue("jsonObjectName").Value<string>("jsonPropertyName");

Y así sucesivamente a partir de ahí.

Esto podría ayudar si no desea asumir el costo de convertir todo el JSON en un objeto C#.

 7
Author: Tony Anderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-16 12:19:41

Si, como yo, prefiere tratar con objetos fuertemente tipeados * * vaya con:

MyObj obj =  JsonConvert.DeserializeObject<MyObj>(jsonString);

De esta manera puede usar intellisense y compile time type error checking.

Puede crear fácilmente los objetos necesarios copiando su JSON en la memoria y pegándolo como objetos JSON (Visual Studio -> Editar -> Pegar Especial -> Pegar JSON como Clases).

Vea aquí si no tiene esa opción en Visual Studio.

También deberá asegurarse de que su JSON sea válido. Agregue su propio objeto al principio si es solo una matriz de objetos. es decir, {"obj":[{},{},{}]}

** Sé que dinámico hace las cosas más fáciles a veces, pero soy un poco ol'skool con esto.

 7
Author: Guy Lowe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-14 05:54:52

Me gusta este método:

using Newtonsoft.Json.Linq;
// jsonString is your JSON-formatted string
JObject jsonObj = JObject.Parse(jsonString);
Dictionary<string, object> dictObj = jsonObj.ToObject<Dictionary<string, object>>();

Ahora puede acceder a cualquier cosa que desee utilizando el dictObj como diccionario. También puede usar Dictionary<string, string> si prefiere obtener los valores como cadenas.

Puede usar este mismo método para convertir como cualquier tipo de objeto.NET.

 5
Author: Blairg23,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-16 12:21:58

Finalmente Obtener El Nombre Del Estado De JSON

Gracias!

Imports System
Imports System.Text
Imports System.IO
Imports System.Net
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Imports System.collections.generic

Public Module Module1
    Public Sub Main()

         Dim url As String = "http://maps.google.com/maps/api/geocode/json&address=attur+salem&sensor=false"
            Dim request As WebRequest = WebRequest.Create(url)
        dim response As WebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
        dim reader As New StreamReader(response.GetResponseStream(), Encoding.UTF8)
          Dim dataString As String = reader.ReadToEnd()

        Dim getResponse As JObject = JObject.Parse(dataString)

        Dim dictObj As Dictionary(Of String, Object) = getResponse.ToObject(Of Dictionary(Of String, Object))()
        'Get State Name
        Console.WriteLine(CStr(dictObj("results")(0)("address_components")(2)("long_name")))
    End Sub
End Module
 0
Author: iApps Creator,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-03 07:59:44

Pedí una Extionclass para json:

 public static class JsonExtentions
    {
        public static string SerializeToJson(this object SourceObject) { return Newtonsoft.Json.JsonConvert.SerializeObject(SourceObject); }


        public static T JsonToObject<T>(this string JsonString) { return (T)Newtonsoft.Json.JsonConvert.DeserializeObject<T>(JsonString); }
}

Diseño-Patrón:

 public class Myobject
    {
        public Myobject(){}
        public string prop1 { get; set; }

        public static Myobject  GetObject(string JsonString){return  JsonExtentions.JsonToObject<Myobject>(JsonString);}
        public  string ToJson(string JsonString){return JsonExtentions.SerializeToJson(this);}
    }

Uso:

   Myobject dd= Myobject.GetObject(jsonstring);

                 Console.WriteLine(dd.prop1);
 0
Author: Sloomy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-08 18:21:17

Bastante tarde a esta fiesta, pero me encontré con este tema a mí mismo hoy en el trabajo. Así es como resolví el problema.

Estaba accediendo a una API de terceros para recuperar una lista de libros. El objeto devolvió un objeto JSON masivo que contenía aproximadamente más de 20 campos, de los cuales solo necesitaba el ID como un objeto de cadena de lista. Utilicé linq en el objeto dinámico para recuperar el campo específico que necesitaba y luego lo inserté en mi objeto de cadena de lista.

dynamic content = JsonConvert.DeserializeObject(requestContent);
var contentCodes = ((IEnumerable<dynamic>)content).Where(p => p._id != null).Select(p=>p._id).ToList();

List<string> codes = new List<string>();

foreach (var code in contentCodes)
{
    codes.Add(code?.ToString());
}
 0
Author: todd.pund,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-12 21:44:45