Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Wie kann ich ein JSON in ein Objekt deserialisieren?
J4m3s90
myCSharp.de - Member



Dabei seit:
Beiträge: 17

Themenstarter:

Wie kann ich ein JSON in ein Objekt deserialisieren?

beantworten | zitieren | melden

Hallo zusammen,

ich hoffe, ich bin im richtigen Bereich gelandet.
Ich möchte eine JSON string als auswertbares Objekt in meinem Programm einfügen.

Das Problem ist, dass ich nur den ersten Wert bekomme und nicht die restlichen.

{"type":"FeatureCollection","metadata":
{"generated":1612941799000,
"url":"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_month.geojson","title":"USGS Significant Earthquakes, Past Month","status":200,"api":"1.10.3","count":13},"features":[{"type":"Feature","properties":
{"mag":6.3,"place":"Bismarck Sea","time":1612676752249,"updated":1612850520358,"tz":null,
"url":"https://earthquake.usgs.gov/earthquakes/eventpage/us6000dfad",
"detail":"https://earthquake.usgs.gov/earthquakes/feed/v1.0/detail/us6000dfad.geojson",
"felt":1,"cdi":7.2,"mmi":4.081,"alert":"green","status":"reviewed","tsunami":0,
"sig":611,"net":"us",
"code":"6000dfad","ids":",us6000dfad,","sources":",us,",
"types":",dyfi,ground-failure,losspager,moment-tensor,origin,phase-data,shakemap,","nst":null,"dmin":1.801,"rms":0.87,"gap":43,"magType":"mww",
"type":"earthquake","title":"M 6.3 - Bismarck Sea"},"geometry":{"type":"Point","coordinates":[146.0591,-3.2929,10]},"id":"us6000dfad"},

{"type":"Feature","properties":{"mag":6,"place":"0 km WSW of Bansalan, Philippines","time":1612671776507,"updated":1612845102813,"tz":null,
"url":"https://earthquake.usgs.gov/earthquakes/eventpage/us6000df9r",
"detail":"https://earthquake.usgs.gov/earthquakes/feed/v1.0/detail/us6000df9r.geojson",
"felt":53,"cdi":8.7,"mmi":6.938,"alert":"green","status":"reviewed","tsunami":0,"sig":600,
"net":"us","code":"6000df9r","ids":",us6000df9r,","sources":",us,","types":",dyfi,ground-failure,losspager,moment-tensor,origin,phase-data,shakemap,","nst":null,"dmin":0.467,"rms":1.38,"gap":37,"magType":"mww","type":"earthquake",
"title":"M 6.0 - 0 km WSW of Bansalan, Philippines"},"geometry":{"type":"Point","coordinates":[125.2056,6.7833,15.55]},"id":"us6000df9r"},

{"type":"Feature","properties":{"mag":6.7,"place":"West Chile Rise",
"time":1612329824293,"updated":1612416513747,"tz":null,
"url":"https://earthquake.usgs.gov/earthquakes/eventpage/us6000de34",
"detail":"https://earthquake.usgs.gov/earthquakes/feed/v1.0/detail/us6000de34.geojson",
"felt":3,"cdi":3.8,"mmi":0,"alert":"green","status":"reviewed","tsunami":1,"sig":692,"net":"us","code":"6000de34",
"ids":",us6000de34,pt21034001,at00qnxtnq,","sources":",us,pt,at,","types":",dyfi,impact-link,losspager,moment-tensor,origin,phase-data,shakemap,","nst":null,"dmin":13.422,"rms":1.07,"gap":70,"magType":"mww","type":"earthquake",
"title":"M 6.7 - West Chile Rise"},"geometry":{"type":"Point","coordinates":[-97.6645,-36.1899,10]},"id":"us6000de34"},

Ansich möchte ich auf die properties zugreifen, habe aber aktuell schon Probleme überhaupt eine Liste zu bekommen mit allen type Werten.

Hatte am Anfang noch public string type zu stehen aber habe nur einen Wert bekommen, bei einer List gibt es eine Exception.
Hat jemand eine Idee wo der Fehler liegt?

Grüße Rob


  class Earthquake
    {
        public int mag { get; set; }
        public string place { get; set; }
        public long time { get; set; }

        public List<string> type { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            WebRequest request = WebRequest.Create("http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_month.geojson");
            WebResponse response = request.GetResponse();

            using (Stream dataStream = response.GetResponseStream())
            {
                // Open the stream using a StreamReader for easy access.
                StreamReader reader = new StreamReader(dataStream);
                // Read the content.
                string responseFromServer = reader.ReadToEnd();
                // Display the content.
                Console.WriteLine(responseFromServer);

                var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
                var earthquake = JsonSerializer.Deserialize<Earthquake>(responseFromServer, options);
                
                }
        }
    }

private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1796
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

Der Aufbau deiner Klasse passt nicht zu dem Json.

Du brauchst hier eine viel umfangreiche Klasse, da type nur ein String ist.
Im Browser wird das ganze i.d.R. auch strukturierter dargestellt, was die Umsetzung der Klasse auch vereinfacht.
Schau dir doch mal die Url in Chrome/Firefox an.

Je nach Ebene musst du schauen welche Struktur du dort hast und muss diese als Property der jeweiligen übergeordneten Struktur umsetzen.

Ich habe auf den ersten Blick folgende Struktur ermittelt.
Diese ist aber unfertig, Properties enthält noch eine Menge Felder die du noch hinzufügen müsstest.
Wenn die Struktur einigermaßen passt, solltest du schon einen guten Teil der Informationen auslesen können.
Kannst dich etwas damit austoben und lernen wie du die Strukturen umsetzen musst.


public class Earthquake
{
    public string Type { get; set; }
	
	public Metadata Metadata { get; set; }
	
	public List<Feature> Features { get; set; }
}

public class Metadata
{
    public long Generated { get; set; }
	
	public string Url { get; set; }
	
	public string Title { get; set; }
	
	public int status { get; set; }
	
	public string Api { get; set; }
	
	public int Count { get; set; }
}

public class Feature
{
	public string Type { get; set; }
	
	public Properties Properties { get; set; }
	
	public string Id { get; set; }
	
	public Geometry Geometry { get; set; }
}

public class Properties
{
	public int Mag { get; set; }
}

public class Geometry
{
	public string Type { get; set; }
	
	public List<double> Coordinates { get; set; }
}

Nachtrag:
Du solltest die Abfrage der Url nicht mehr mit WebRequest/WebResponse machen.
Nutzt dazu am besten den HttpClient, da WebRequest nicht mehr weiterentwickelt wird und auch in der Doku darauf verwiesen wird.

Hinweis bei WebRequest

T-Virus
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von T-Virus am .
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Zitat
ich hoffe, ich bin im richtigen Bereich gelandet.
... wars leider nicht (genauso wenig die richtigen Code Tags :-) - aber ich habs korrigiert.

Nimm einfach Refit für sowas; kannste in ner Handvoll Zeilen Quellcode umsetzen und bekommst 90% geschenkt.
reactiveui/refit
private Nachricht | Beiträge des Benutzers
J4m3s90
myCSharp.de - Member



Dabei seit:
Beiträge: 17

Themenstarter:

beantworten | zitieren | melden

Danke dir, probiere ich nachher gleich aus.
Mir ging es auch nicht darum, dass jemand mir alles erstellt.
Brauchte nur einen Denkanstoß!

Danke dir!
private Nachricht | Beiträge des Benutzers
J4m3s90
myCSharp.de - Member



Dabei seit:
Beiträge: 17

Themenstarter:

beantworten | zitieren | melden

Was mache ich denn bei Name mit einen Leerzeichen dazwischen?


    "Meta Data": {
        "1. Information": "Heavy",
        "2. Symbol": "Paul",
        "3. Last Hit": "2021-02-09 19:55:00",
        "4. Output Size": "Compact",

    },

Danke auch für den Hinweis auf das Git Projekt , allerdings wollte ich es lieber mit den Standard Funktionsumfang erstellen.
Schaue es mir aber trotzdem an.
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1796
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

Wo kommt den der Fall her?
In dem Beispiel liegt gibt es keine Leerzeichen in den Metadata.
Bitte mal den Link posten wo das vorkommt, dann muss man auch erstmal prüfen ob dort nicht eine andere Struktur nötig ist.

T-Virus
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers
J4m3s90
myCSharp.de - Member



Dabei seit:
Beiträge: 17

Themenstarter:

beantworten | zitieren | melden

link zur anfrage!
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 225

beantworten | zitieren | melden

Siehe: https://json2csharp.com/


// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); 
    public class MetaData    {
        [JsonProperty("1.Information")]
        public string _1Information { get; set; } 
        [JsonProperty("2.Symbol")]
        public string _2Symbol { get; set; } 
        [JsonProperty("3.LastHit")]
        public string _3LastHit { get; set; } 
        [JsonProperty("4.OutputSize")]
        public string _4OutputSize { get; set; } 
    }

    public class Root    {
        public MetaData MetaData { get; set; } 
    }



private Nachricht | Beiträge des Benutzers
J4m3s90
myCSharp.de - Member



Dabei seit:
Beiträge: 17

Themenstarter:

beantworten | zitieren | melden

Hey JimStark,

das hatte ich auch schon gesehen, allerdings sagt mir hier mein VS, dass JsonProperty keine Attributklasse ist.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Bitte beachten, dass json2sharp leider oft keine korrekten Resultate erzeugt; vor allem nicht mit .NET Core und System.Text.Json!
Auch hier fehlt das Leerzeichen in der JsonProperty.
Zitat
JsonProperty keine Attributklasse ist.
Dann fehlt Dir einfach das Using.
Siehe Basics zu Json: Serialisieren und Deserialisieren von JSON mit C# – .NET
private Nachricht | Beiträge des Benutzers
J4m3s90
myCSharp.de - Member



Dabei seit:
Beiträge: 17

Themenstarter:

beantworten | zitieren | melden

Habe ich beide, aber der Fehler steht trotzdem noch an.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;

using System.Text.RegularExpressions;

namespace Test
{
    class Earthquake
    {
        public int mag { get; set; }
        public string place { get; set; }
        public long time { get; set; }

        public List<string> type { get; set; }
    }
    public class Joa
    {
        
   
        public string BindingType { get; set; }
        [JsonProperty("Meta Data")]
        public Metadata Metadata { get; set; }
    }
    public class Metadata
    {
        public string Information { get; set; }
        public string Symbol { get; set; }
        public DateTime LastRefreshed { get; set; }
        public string Interval { get; set; }
        
    }
    class Program
    {
        static readonly HttpClient client = new HttpClient();
        static void Main(string[] args)
        {
            Task task = Main();
            while (true)
            {

            }
        }
        static async Task Main()
        {
            HttpResponseMessage response = await client.GetAsync("https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=MSFT&apikey=demo");
            response.EnsureSuccessStatusCode();

            string responseBody = await client.GetStringAsync("https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=MSFT&apikey=demo");
            Console.WriteLine(responseBody);
            var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
            var joa = JsonSerializer.Deserialize<Joa>(responseBody, options);


        }
    }
}

private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1796
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

Die while(true) Schleife kannst du wieder rauswerfen.
Ebenfalls kannst du auch Main als async von .NET aufrufen lassen.
Dann sparst du dir die Überladungen.

T-Virus
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Zitat von J4m3s90
Habe ich beide, aber der Fehler steht trotzdem noch an.

Ich hab Dir einen Link gegeben, damit Du ihn durchliest.
Wenn Du Hilfe nicht durchlesen magst, dann musst es einfach sagen.

Bei System.Text.Json heisst es JsonPropertyName, nicht JsonProperty.
How to migrate from Newtonsoft.Json to System.Text.Json



private Nachricht | Beiträge des Benutzers
J4m3s90
myCSharp.de - Member



Dabei seit:
Beiträge: 17

Themenstarter:

beantworten | zitieren | melden

Tatsächlich hatte ich den Teil aus einem Beispiel noch im Programm.
Danke, hatte die Seite heute früh schon 2 mal gelesen!
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von J4m3s90 am .
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Offensichtlich nicht, denn Du verwendest immer noch JsonProperty statt JsonPropertyName.
Willst Du das beibehalten, dann kannst eben nicht mit System.Text.Json arbeiten sondern brauchst Newtonsoft.Json.

Verwendest Du dann entsprechend das using richtig, dann gibt es auch den Fehler nicht.
Ansonsten hast Du das einzigen Fall im gesamten Universum, bei dem es anders wäre.
private Nachricht | Beiträge des Benutzers
J4m3s90
myCSharp.de - Member



Dabei seit:
Beiträge: 17

Themenstarter:

beantworten | zitieren | melden

Halt Moment

Ich glaube da ist jetzt was nicht richtig rüber gekommen. Habe den Text heute früh gelesen, aber den Sinn hinter dem zweiten Using nicht verstanden. Deshalb habe ich den eben kurz rein genommen.

Nach deinem Hinweis habe ich natürlich auf JsonPropertyName gewechsel und es ging, deshalb auch das Danke!
War nur ein Missverständis!

Eine Frage wäre noch offen. Wie lese ich jetzt die Time Series ein. Diese ändert sich ja täglich. Bevor ich es mit einer Auswertung vom String mache, gibt es hier auch eine Möglichkeit über JsonSerializer?

Grüße und vielen Dank für die bisherige Unterstützung !!
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Bitte nimm Dir doch für solche Fragen wenigstens 10 Sekunden Zeit um zu schauen, ob das nicht schon in der Dokumentation steht :-)
Das ist echt nicht zuviel verlangt. Siehe auch [Hinweis] Wie poste ich richtig?

Newtonsoft hat von Haus aus einen UnixDateTimeConverter.

https://www.newtonsoft.com/json/help/html/DatesInJSON.htm
Und damit Du den richtigen Typ für Zeiten in .NET verwendest: [FAQ] DateTime vs. DateTimeOffset und der Umgang mit Zeiten in .NET
private Nachricht | Beiträge des Benutzers
J4m3s90
myCSharp.de - Member



Dabei seit:
Beiträge: 17

Themenstarter:

beantworten | zitieren | melden

Habe ich gesehen.
Habe aber auch oben schon geschrieben, dass ich gerne auf fremde Bibliotheken verzichten möchte.
Okay, dann mache ich die Auswertung einfach im String.

Danke euch für die Hilfe!
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Du weisst schon, dass Newtonsoft eine externe Bibliothek ist, die Du da verwendest (auch wenn der Macher mittlerweile bei Microsoft ist)?
Du weißt schon, dass das Ökosystem von .NET darauf basiert, dass externe Pakete verwendet werden?

Wenn Du das nicht willst, dann bist mit .NET (und eigentlich mit jeder anderen Technologie) falsch.
Gibt quasi kein modernes Ökosystem, das nicht mit externen Paketen gedacht ist.

Aber gut; manchmal muss man im Leben Fehler machen, um draus zu lernen.
Viel Erfolg! :-)
private Nachricht | Beiträge des Benutzers
J4m3s90
myCSharp.de - Member



Dabei seit:
Beiträge: 17

Themenstarter:

beantworten | zitieren | melden

Deshalb verwende ich auch kein Newtonsoft!
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Na, wenn Du jetzt doch schon System.Text.Json verwendest, dann hast ja vorher schon den Link bekommen, wie man Strings in DateTimeOffset serialisiert.
Dann hat sich ja die Frage schon erledigt. Perfekt. Top!

Ist dann auch mein letzter Beitrag hier
private Nachricht | Beiträge des Benutzers
J4m3s90
myCSharp.de - Member



Dabei seit:
Beiträge: 17

Themenstarter:

beantworten | zitieren | melden

Aktuell mache ich das noch ja.
Wenn es nachher wirklich nicht so will, dann werde ich vermutlich doch mal Newtonsoft probieren.

Im Beispiel unten fehlt mir noch bei TimeSeries die ganzen anderen Werte.
Ansonsten bin ich schon sehr zufrieden , wollte hier nur wissen ob es dort direkt eine Variante gibt die ich benutzen kann, oder ob ich mir was zusammen bauen muss.


  public class Joa
    {

        [JsonPropertyName("Meta Data")]
        public Metadata Metadata { get; set; }
        [JsonPropertyName("Time Series (Daily)")]

        public TimeSeries TimeSeries { get; set; }
    }

    public class TimeSeries
    {
        //hier jetzt die einzelnen Daten als Member anlegen?
        [JsonPropertyName("2021-02-09")] // Da sich der Wert jeden Tag verändert, bzw. Tage es nachher in Minuten ablaufen soll und nicht Tagen, brauche ich hier noch eine alternative!
               Datum Datum { get; set; }
    }

    public class Datum
    {
        [JsonPropertyName("1. open")]
        public double Open { get; set; }
        [JsonPropertyName("2. high")]
        public double High { get; set; }
        [JsonPropertyName("3. low")]
        public double Low { get; set; }

    }
    public class Metadata
    {
        [JsonPropertyName("1. Information")]
        public string Information { get; set; }
        [JsonPropertyName("2. Symbol")]
        public string Symbol { get; set; }
        [JsonPropertyName("3. Last Refreshed")]
        public DateTime LastRefreshed { get; set; }   
    }

private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 225

beantworten | zitieren | melden

Von welchen JSON Daten sprichst du jetzt?
Das ist nicht mehr das von oben? Zeig mal ein Beispiel
private Nachricht | Beiträge des Benutzers
J4m3s90
myCSharp.de - Member



Dabei seit:
Beiträge: 17

Themenstarter:

beantworten | zitieren | melden

Ich rede von den Daten
private Nachricht | Beiträge des Benutzers
david.m
myCSharp.de - Member



Dabei seit:
Beiträge: 108

beantworten | zitieren | melden

Die "Time Series (Daily)" sehen für mich wie ein Dictionary aus, wo der Key der Tag ist.


public class TimeSeries: Dictionary<string, Datum>
{
}

ggf. geht auch folgendes


public class TimeSeries: Dictionary<DateTime, Datum>
{
}

Musst mal sehen.
private Nachricht | Beiträge des Benutzers
J4m3s90
myCSharp.de - Member



Dabei seit:
Beiträge: 17

Themenstarter:

beantworten | zitieren | melden

Sehr gute Idee,
damit sind alle meine Fragen beantwortet.
Es hat alles so funktioniert wie es soll und ich kann auf alle Daten zugreifen .

Habe es mit :


 public Dictionary<string,Datum> TimeSeries { get; set; }

gemacht!

Vielen Dank an alle und sorry wenn ich zu wenig in der Dokumentation geschaut habe.
(*Sorry Abt *)
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15618
Herkunft: BW

beantworten | zitieren | melden

Brauchst Dich bei mir nicht entschuldigen.
Du tust Dir selbst keinen Gefallen / schadest Dir selbst, wenn Du nicht in die Doku schaust und so schneller (und sicher) an Deine Antwort kommst. ¯\_(ツ)_/¯
private Nachricht | Beiträge des Benutzers