2013-03-19 1 views
6

Ich versuche, eine JSON-Struktur mit Json.NET zu verarbeiten und stießen auf einige Probleme:Json.NET: Deserialisieren json Arrays

Meine Klassen funktionieren nicht, wenn ein JSON eine unbenannte Array enthält.

Json Beispiel:

{ 
    "graph_property" : [{ 
      "name" : "calculation_method", 
      "value" : "Arithmetic" 
     }, { 
      "name" : "graph_type", 
      "value" : "TIME" 
     } 
    ], 
    "measurement" : [{ 
      "id" : "9997666", 
      "alias" : "Measurement (TxP)[IE]-Home Page - Total Time (seconds)", 
      "bucket_data" : [{ 
        "name" : "2013-MAR-18 12:00 AM", 
        "id" : 1, 
        "perf_data" : { 
         "value" : "2.244", 
         "unit" : "seconds" 
        }, 
        "avail_data" : { 
         "value" : "99.67", 
         "unit" : "percent" 
        }, 
        "data_count" : { 
         "value" : "299", 
         "unit" : "#" 
        } 
       } 
      ], 
      "graph_option" : [{ 
        "name" : "perfwarning", 
        "value" : "-", 
        "unit" : "seconds" 
       }, { 
        "name" : "perfcritical", 
        "value" : "-", 
        "unit" : "seconds" 
       }, { 
        "name" : "availwarning", 
        "value" : "-", 
        "unit" : "percent" 
       }, { 
        "name" : "availcritical", 
        "value" : "-", 
        "unit" : "percent" 
       }, { 
        "name" : "bucketsize", 
        "value" : "86400", 
        "unit" : "seconds" 
       }, { 
        "name" : "rows", 
        "value" : "1", 
        "unit" : "#" 
       }, { 
        "name" : "pagecomponent", 
        "value" : "Total Time", 
        "unit" : "seconds" 
       }, { 
        "name" : "avg_perf", 
        "value" : "2.244", 
        "unit" : "seconds" 
       }, { 
        "name" : "avg_avail", 
        "value" : "99.67", 
        "unit" : "percent" 
       }, { 
        "name" : "total_datapoint_count", 
        "value" : "300", 
        "unit" : "#" 
       }, {} 

      ] 
     }, { 
      "id" : "9997666", 
      "alias" : "Measurement (TxP)[IE]-Women - Total Time (seconds)", 
      "bucket_data" : [{ 
        "name" : "2013-MAR-18 12:00 AM", 
        "id" : 1, 
        "perf_data" : { 
         "value" : "0.979", 
         "unit" : "seconds" 
        }, 
        "avail_data" : { 
         "value" : "100.00", 
         "unit" : "percent" 
        }, 
        "data_count" : { 
         "value" : "299", 
         "unit" : "#" 
        } 
       } 
      ], 
      "graph_option" : [{ 
        "name" : "perfwarning", 
        "value" : "-", 
        "unit" : "seconds" 
       }, { 
        "name" : "perfcritical", 
        "value" : "-", 
        "unit" : "seconds" 
       }, { 
        "name" : "availwarning", 
        "value" : "-", 
        "unit" : "percent" 
       }, { 
        "name" : "availcritical", 
        "value" : "-", 
        "unit" : "percent" 
       }, { 
        "name" : "bucketsize", 
        "value" : "86400", 
        "unit" : "seconds" 
       }, { 
        "name" : "rows", 
        "value" : "1", 
        "unit" : "#" 
       }, { 
        "name" : "pagecomponent", 
        "value" : "Total Time", 
        "unit" : "seconds" 
       }, { 
        "name" : "avg_perf", 
        "value" : "0.979", 
        "unit" : "seconds" 
       }, { 
        "name" : "avg_avail", 
        "value" : "100.00", 
        "unit" : "percent" 
       }, { 
        "name" : "total_datapoint_count", 
        "value" : "299", 
        "unit" : "#" 
       }, {} 

      ] 
     } 
    ], 
    "link" : { 
     "type" : "application/json", 
     "href" : "http://api.website.tld?format=json", 
     "rel" : "slotmetadata" 
    } 
} 

Klasse für Json.NET:

using System; 
using System.Collections.Generic; 

namespace CAKR.Graph 
{ 
    /// <summary> 
    /// Description of KN_Graph. 
    /// </summary> 
    public class GraphProperty 
    { 
     public string name { get; set; } 
     public string value { get; set; } 
    } 

    public class PerfData 
    { 
     public string value { get; set; } 
     public string unit { get; set; } 
    } 

    public class AvailData 
    { 
     public string value { get; set; } 
     public string unit { get; set; } 
    } 

    public class DataCount 
    { 
     public string value { get; set; } 
     public string unit { get; set; } 
    } 

    public class BucketData 
    { 
     public string name { get; set; } 
     public int id { get; set; } 
     public PerfData perf_data { get; set; } 
     public AvailData avail_data { get; set; } 
     public DataCount data_count { get; set; } 
    } 

    public class GraphOption 
    { 
     public string name { get; set; } 
     public string value { get; set; } 
     public string unit { get; set; } 
    } 

    public class Measurement 
    { 
     public string id { get; set; } 
     public string alias { get; set; } 
     public List<BucketData> bucket_data { get; set; } 
     public List<GraphOption> graph_option { get; set; } 
    } 

    public class Link 
    { 
     public string type { get; set; } 
     public string href { get; set; } 
     public string rel { get; set; } 
    } 

    public class RootObject 
    { 
     public List<GraphProperty> graph_property { get; set; } 
     public List<Measurement> measurement { get; set; } 
     public Link link { get; set; } 
    } 
} 

Mein Code:

var myObject = JsonConvert.DeserializeObject<CAKR.Graph.Measurement>(MyJsonString); 

Ich bin nicht s Warum bekomme ich kein Objekt mit den Daten des "Measurment" Kind-Arrays. Wenn ich benannte Werte einfügen, funktioniert es ...

+0

hier ist eine gute Verbindung in der Zukunft zu verwenden zu überprüfen, ob Ihre JSON gültig ist oder nicht [JSON Lint] (http: // jsonlint. com /) – MethodMan

+0

Sollten Sie nicht gegen eine 'Class' und nicht für einen' Namespace' arbeiten? 'CAKR.Graph.Measurement' ist keine Klasse – MethodMan

+0

mögliches Duplikat von [JSON-Array in JSON.NET nicht deserialisieren] (http: //stackoverflow.com/questions/9452901/cannot-deserialize-json-array-into-type-json-net) – MethodMan

Antwort

4

Sie sind fast da. Nur

var myObject = JsonConvert.DeserializeObject<CAKR.Graph.RootObject>(MyJsonString); 

statt

var myObject = JsonConvert.DeserializeObject<CAKR.Graph.Measurement>(MyJsonString); 
+0

Das dachte ich zuerst. Aber Measurement Object bleibt aus irgendeinem Grund "NULL". – t313

2

Zunächst einmal verwenden, brauchen Sie nicht wirklich alle Eigenschaften Ihrer Measurement Klasse zu nennen genau so, wie sie in MyJsonString präsentiert werden. Sie können das Attribut JsonProperty verwenden und Ihre Klasseneigenschaften dekorieren.

Eine andere Sache ist, wenn Sie einen Teil Ihres MyJsonString deserialisieren möchten und nur Array von Measurement zu extrahieren, sollten Sie (in Ihrem Fall korrekt T-Typ für Deserialize Methode bieten, es ist IEnumerable<Measurement>

Der folgende Code sollte helfen.

dynamic context = JObject.Parse(MyJsonString); 
    var myObject = JsonConvert.DeserializeObject<IEnumerable<Measurement>>(context.measurement.ToString()); 
+0

Danke Jevgenij! Das hat mich wirklich auf etwas gebracht. – t313

+0

Gern geschehen. –

8

so. ich war schon seit geraumer Zeit zu kämpfen diese Arbeit bekommen jedoch am Ende die Lösung nicht so schwierig ist. ich hoffe mit meiner Antwort werde ich einige Menschen helfen.

Die Lösung in meinem Fall war

  1. JSON.net in Ihr Projekt Installieren von
  2. einschließlich Ihrem JSON-Objekt unter Verwendung der nu.get Arrays in Arrays etc. Stellen Sie sicher, dass das Format des Objekts korrekt ist ! Beispiel ...

{ "Product": [

{ 
     "ProjectImg" : "http://placehold.it/400x300", 
     "Category"  : "Cars", 
     "ProjectTitle" : "Cars of the future", 
     "ProjectDesc" : "Test project", 
     "GenSpecList" : ["Specs1", "Specs2", "Specs3", "Specs4"], 
     "OptionList" : [{ "OptionNr" : "1", 
           "Options" : ["Opt1", "Opt2", "Opt3"] 
          }, 
          { "OptionNr" : "2", 
           "Options" : ["Opt1", "Opt2", "Opt3"] 
          }, 
          { "OptionNr" : "3", 
           "Options" : ["Opt1", "Opt2", "Opt3"] 
          }, 
          { "OptionNr" : "4", 
           "Options" : ["Opt1", "Opt2", "Opt3"] 
          }, 
          { "OptionNr" : "5", 
           "Options" : ["Opt1", "Opt2", "Opt3"] 
          }, 
          { "OptionNr" : "6", 
           "Options" : ["Opt1", "Opt2", "Opt3"] 
          } 
         ], 
     "Articles"  : [{ "tileImg" : "'Images/Project/1.jpg'", 
           "tileTit" : "Title1", 
           "tileArt" : "Article text here..." 
          }, 
          { 
           "tileImg" : "'Images/Project/2.jpg'", 
           "tileTit" : "Title2", 
           "tileArt" : "Article text here..." 
          }, 
          { 
           "tileImg" : "'Images/Project/3.jpg'", 
           "tileTit" : "Title3", 
           "tileArt" : "Article text here..." 
          }, 
          { 
           "tileImg" : "'Images/Project/4.jpg'", 
           "tileTit" : "Title4", 
           "tileArt" : "Article text here..." 
          } 
         ] 
    } 
] 
} 
  1. Zum json2csharp.com und kopieren Sie Ihre JSON-Objekt in das Eingabefeld ein und klicken Sie auf die Schaltfläche generieren. Kopiere das csharp-Modell (das war eigentlich der Schlüssel, um meinen Kampf zu lösen!), Der in dein ViewModel generiert wurde.
  2. In meinem Fall die primäre Klasse aller generierten Klassen von json2csharp.com war die RootObject und sah aus wie unten

    public class Article 
    { 
        public string tileImg { get; set; } 
        public string tileTit { get; set; } 
        public string tileArt { get; set; } 
    } 
    
    public class OptionList 
    { 
        public string OptionNr { get; set; } 
        public List<string> Options { get; set; } 
    } 
    
    public class ProductDetail 
    { 
        public string ProjectImg { get; set; } 
        public string Category { get; set; } 
        public string ProjectTitle { get; set; } 
        public string ProjectDesc { get; set; } 
        public List<string> GenSpecList { get; set; } 
        public List<OptionList> OptionList { get; set; } 
        public List<Article> Articles { get; set; } 
    } 
    
    public class RootObject 
    { 
        public List<ProductDetail> ProductDetail { get; set; } 
    } 
    
  3. dann den folgenden Code in der Steuerung verwenden (nur die komplette Datei hier kopiert)

    using Project.Details; //<-- this is my ViewModel namespace name 
    using Newtonsoft.Json; 
    using System.IO; 
    using System.Threading.Tasks; 
    
    namespace WebApplication.Controllers 
    { 
        public class JSONController : Controller 
        { 
         // 
         // GET: /JSON/ 
         public async Task<ActionResult> Index() 
         { 
          StreamReader file = new StreamReader("C:\\Users\\YourName\\etc\\File.json"); 
          String json = await file.ReadToEndAsync(); 
    
          var Project = JsonConvert.DeserializeObject<RootObject>(json); 
    
          return View(); 
         } 
        } 
    } 
    

in Nun sollte alles funktionieren, Arrays Arrays usw. Hoffe, dass Sie meine Lösung hilfreich gefunden haben, beachten Sie, dass ich nicht ein hartes Programmierer bin, also wenn ich Dinge auf der Wirksamkeit vermisse, hoffe ich, einige Tipps von Ihnen zu erhalten, diesen Code zu verbessern ...

Mit freundlichen Grüßen, Raymond

+0

Ich möchte den Schlüsselwert und den Wert erhalten ... tut es das? Danke – Si8

0

Ich benutze eine sehr einfache Methode zur Deserialisierung Json Arrays. Anstatt eine Tonne öffentlicher Klassen mit zahlreichen öffentlichen Variablen zu verwenden. Ich benutze nur ein dynamisches Objekt und übergebe json als Objekt an JSONConvert.DeserializeObject.

So würde es funktionieren. Sagen, dass ich die folgende JSON haben:

string json = { 'Name': 'John Doe', 
    'Address': { 'City': 'Atlanta', 'State': 'GA' }, 
    'Age': 30} 

Ich kann Zeichenfolge json zum JSONConvert.DeserializeObject passieren.

Dann mit dem dynamischen Element, das gerade erstellt wurde, kann ich Json Daten wie so sammeln.

string getName = outputArray.Name //This will return "John Doe" 

Wenn Sie ein Array in Ihrem Json haben, können Sie

verwenden
string getCity = outputArray.Address.City; //This will return "Atlanta". 

Es ist sehr einfach zu ändern, in dem Sie Daten aus, ohne einen Cluster von öffentlichen Variablen Nachziehen ... Sie noch die sparen Werte zu öffentlichen Variablen, wenn Sie möchten.

Nachstehend ist, wie ich die komplette Methode:

using (var client = new WebClient()) 
     { 
      string json = client.DownloadString(url); 
      string output = json.ToString(); 

      dynamic outputArray = JsonConvert.DeserializeObject(output); 

      string _age = outputArray.age; 
      string appID = outputArray.data.app_id; 

      Debug.Write(outputArray.Something); //Just match value of json   
     } 
+0

falsches Beispiel, sobald dein JSON kein Array ist, nur ein Objekt –

Verwandte Themen