Désérialisation du JSON to.NET objet utilisant Newtonsoft (ou LINQ à JSON peut-être?)

je sais qu'il y a quelques billets sur Newtonsoft donc j'espère que ce n'est pas exactement une répétition...J'essaie de convertir les données de JSON retournées par L'API de Kazaa en une sorte d'objet sympa

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();

cette ligne JsonConvert est la plus récente que j'ai essayé...Je ne comprends pas tout à fait et j'espérais éliminer un peu de jeu de jambes en vous demandant les gars. J'essayais à l'origine de le transformer en Dictionnaire ou quelque chose comme ça...et en fait, j'ai juste besoin d'accrocher une quelques valeurs là-dedans donc à en juger par la documentation, peut-être LINQ de Newtonsoft à JSON pourrait être un meilleur choix? Pensées / Liens?

voici un exemple des données de retour de 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": "u76e7u5de7u97f3"
    },
    {
      "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
}

j'ai fait plus de lecture et j'ai trouvé le LINQ de Newtonsoft à JSON est exactement ce que je voulais...en utilisant WebClient, Stream, StreamReader, et Newtonsoft...Je peux cliquer sur Kazaa pour les données JSON, extraire une URL, télécharger le fichier, et tout faire en comme sept lignes de code! Je l'aime.

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();

ce post reçoit tellement de hits j'ai pensé qu'il pourrait être utile d'inclure les bits "d'utilisation" qui sont discutés dans les commentaires.

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"]);
}
279
demandé sur Tim Sylvester 2011-01-20 19:19:51

11 réponses

si vous avez juste besoin d'obtenir quelques éléments de l'objet JSON, je voudrais utiliser Json.NET classe LINQ à JSON JObject . Par exemple:

JToken token = JObject.Parse(stringFullOfJson);

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

j'aime cette approche parce que vous n'avez pas besoin de désérialiser complètement l'objet JSON. Cela est pratique avec les API qui peuvent parfois vous surprendre avec des propriétés d'objets manquants, comme Twitter.

de la Documentation: la Sérialisation et la Désérialisation de JSON avec Json.NET et LINQ to JSON with Json.NET

230
répondu arcain 2017-05-16 12:14:16

vous pouvez utiliser le type C# dynamic pour faciliter les choses. Cette technique simplifie également la reconfiguration puisqu'elle ne s'appuie pas sur des chaînes magiques.

JSON

la chaîne JSON ci-dessous est une réponse simple à un appel D'API HTTP, et elle définit deux propriétés: Id et Name .

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

c#

Use JsonConvert.DeserializeObject<dynamic>() pour désérialiser cette chaîne en un type dynamique, il suffit d'accéder à ses propriétés de la manière habituelle.

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

si vous spécifiez le type de la variable results comme dynamic , au lieu d'utiliser le mot-clé var , alors les valeurs de propriété seront correctement deserialize, par exemple Id à un int et pas un JValue (merci à GFoley83 pour le commentaire ci-dessous).

Note : Le lien NuGet pour L'assemblage Newtonsoft est http://nuget.org/packages/newtonsoft.json .

236
répondu biofractal 2017-11-22 22:57:13

avec le mot-clé dynamic , il devient vraiment facile de parser n'importe quel objet de ce genre:

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
répondu Sushant Srivastava 2017-05-16 12:17:42

corrigez - moi si je me trompe, mais l'exemple précédent, je crois, est juste un peu en décalage avec la dernière version de James Newton Json.NET bibliothèque.

var o = JObject.Parse(stringFullOfJson);
var page = (int)o["page"];
var totalPages = (int)o["total_pages"];
21
répondu Rick Leitch 2011-01-20 17:54:54

Désérialiser et obtenir la valeur (lorsque la collection est dynamique):

// 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
répondu Arun Prasad E S 2018-01-15 01:58:33

en outre, si vous êtes à la recherche d'une valeur spécifique imbriquée dans le contenu JSON, vous pouvez faire quelque chose comme cela:

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

et ainsi de suite.

cela pourrait aider si vous ne voulez pas supporter le coût de conversion de L'ensemble JSON en un objet C#.

7
répondu Tony Anderson 2017-05-16 12:19:41

Si vous, comme moi, préfèrent traiter avec des objets fortement typés** aller à:

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

de cette façon, vous pouvez utiliser intellisense et compiler la vérification d'erreur de type de temps.

vous pouvez facilement créer les objets nécessaires en copiant votre JSON en mémoire et en le collant comme des objets JSON (Visual Studio -> Edit -> Paste Special -> Paste JSON as Classes).

Voir ici si vous n'avez pas cette option dans Visual Studio.

vous devrez également vous assurer que votre JSON est valide. Ajouter vos propres objets au début si c'est juste un tableau d'objets. c'est à dire { "obj": [{},{},{}]}

** je sais que dynamique rend les choses plus facile parfois, mais je suis un peu ol'skool avec cette.

7
répondu Guy Lowe 2017-07-14 05:54:52

j'aime cette méthode:

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

vous pouvez maintenant accéder à tout ce que vous voulez en utilisant le dictObj comme un dictionnaire. Vous pouvez également utiliser Dictionary<string, string> si vous préférez obtenir les valeurs des chaînes de caractères.

vous pouvez utiliser cette même méthode pour lancer que tout type d'objet .NET.

5
répondu Blairg23 2017-05-16 12:21:58

enfin obtenir le nom D'État de JSON

Merci!

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
répondu iApps Creator 2018-06-03 07:59:44

j'ai inscrit une classe D'exception pour 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); }
}

Design-Pattern:

 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);}
    }

Utilisation:

   Myobject dd= Myobject.GetObject(jsonstring);

                 Console.WriteLine(dd.prop1);
0
répondu Sloomy 2018-06-08 18:21:17

assez tard à cette fête, mais je suis tombé sur cette question moi-même aujourd'hui au travail. Voici comment j'ai résolu le problème.

j'accédais à une API tierce partie pour récupérer une liste de livres. L'objet a retourné un objet JSON massif contenant environ 20 champs+, dont je n'avais besoin que de L'ID comme un objet List string. J'ai utilisé linq sur l'objet dynamic pour récupérer le champ spécifique dont j'avais besoin et je l'ai ensuite inséré dans mon objet List string.

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
répondu todd.pund 2018-07-12 21:44:45