Laden...

JsonConvert Deserialize gibt keinen Inhalt auf Console aus

Erstellt von VisualCsharpNoob vor einem Jahr Letzter Beitrag vor einem Jahr 375 Views
V
VisualCsharpNoob Themenstarter:in
5 Beiträge seit 2022
vor einem Jahr
JsonConvert Deserialize gibt keinen Inhalt auf Console aus

Hallo, ich versuche einen bestimmten Wert aus einer Wetterdienst API in Form eines Json Files auszulesen.
Ich kann die gesamte Json File in der Variable jsonInhalt anzeigen lassen aber sobald ich aus der Klasse einen bestimmten Wert rauspicken möchte, bleibt die Variable leer. Der Compiler (visual studio) spuckt auch keine Fehlermeldung raus, die abgerufene Variable bleibt einfach leer.
Hab da irgendeinen Matrixfehler im Hirn und kommt nicht drauf bzw. ich hab das Konzept dahinter wohl noch nicht verstanden 🙁


var client = new HttpClient();

try
{
    var request = new HttpRequestMessage(HttpMethod.Get, "http://api.weatherapi.com/v1/current.json?key=************"); //Key anonymisiert für den Post, die Seite ist aber abrufbar.
    var response = await client.SendAsync(request);
    response.EnsureSuccessStatusCode();
    var jsonInhalt = await response.Content.ReadAsStringAsync();
   Console.WriteLine(jsonInhalt); // Dieser Inhalt wird komplett angezeigt in der Console

    Location myHome = JsonConvert.DeserializeObject<Location>(jsonInhalt);

    Console.WriteLine(myHome.localtime); // Dieser Inhalt wird NICHT angezeigt in der Console. Keine Fehlermeldung
    Console.ReadLine();

catch (Exception e)
{
    Console.WriteLine(e.Message);
}

finally
{
    client.Dispose();
}

public class Location
{
    public string localtime { get; set; }
}


Wo ist da mein Denkfehler?

T
2.219 Beiträge seit 2008
vor einem Jahr

Hast du schonmal den Debugger verwendet und geschaut was du zurückbekommst?
Ich tippe mal darauf, dass der String null ist, weil das Feld nicht richtig deserialisiert wird.
Dadurch wird dann auch nichts angezeigt.
Kannst du aber mit dem Debugger prüfen.

Nachtrag:
Laut Doku rufst du die Realtime Api auf.
Die liefert dir auch kein Location Objekt, sondern ein Current Objekt.

Doku:
[

Weather and Geolocation API - Free Weather and Geolocation API JSON and XML - WeatherAPI.com](https://www.weatherapi.com/docs/?PageSpeed=noscript#apis-realtime)

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.

D
261 Beiträge seit 2015
vor einem Jahr

Mit deinem aktuellen Vorgehen müsste "localtime" ein Key-Value Paar des Root-Objekts sein. Es ist liegt aber unterhalb von "location":


{
    "location": {
//        ...
        "localtime": "2022-06-26 18:48"
    },
    "current": {
//        ...
    }
}

Du musst das so auch in deinen C# Klassen abbilden:


public class Rootobject
{
    public Location location { get; set; }
}

public class Location
{
    public string localtime { get; set; }
}

Das kann Visual Studio automatisch für dich machen, wenn du den folgenden Menüpunkt aufrufst, während dein JSON in der Zwischenablage liegt: Edit - Paste Special - Paste JSON as Classes

PS: Es ist hilfreich für die Leute im Forum, wenn man bei solchen Fragen das zugehörige JSON zur Verfügung stellt.

Edit:
@T-Virus: Die Doku der Api ist nicht wirklich schön. Ich habe zumindest auf die schnelle kein komplettes Beispiel gefunden und deswegen schnell einen Wegwerf-Account erstellt. Aber nachträglich habe ich jetzt in der Doku unter "Location" gelesen:

Location Object

Location object is returned with each API response. [...]

V
VisualCsharpNoob Themenstarter:in
5 Beiträge seit 2022
vor einem Jahr

Erstmal super vielen Dank für eure schnellen Antworten.

Hast du schonmal den Debugger verwendet und geschaut was du zurückbekommst?
Ich tippe mal darauf, dass der String null ist, weil das Feld nicht richtig deserialisiert wird.
Dadurch wird dann auch nichts angezeigt.
Kannst du aber mit dem Debugger prüfen.

Nachtrag:
Laut Doku rufst du die Realtime Api auf.
Die liefert dir auch kein Location Objekt, sondern ein Current Objekt.

Doku:

>

T-Virus

Hier ist die volle Adresse (inkl. Key) übrigens die ich nutze
https://api.weatherapi.com/v1/current.json?key=592738e65d4247ccbf3192905222606&q=London&aqi=no

ist quasi die standardseite als beispiel. Du hast im Übrigen recht, dass bei mir der Debugger mich auf null values hinweist

CS8600 Converting null literal or possible null value to non-nullable type.
CS8602 Dereference of a possibly null reference.
CS8618 Non-nullable property 'localtime' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Aber ich weiß nicht ob da das Problem steckt.
Anscheinend komm ich mit den Objekt und Klassenbezeichnungen durcheinander oder ich hab explizit mit der weatherapi Json ein Problem, denn andere APIS funktionieren und geben mir Werte raus

V
VisualCsharpNoob Themenstarter:in
5 Beiträge seit 2022
vor einem Jahr

Das kann Visual Studio automatisch für dich machen, wenn du den folgenden Menüpunkt aufrufst, während dein JSON in der Zwischenablage liegt: Edit - Paste Special - Paste JSON as Classes

Supertip. Danke dafür!
Ich hab das genutzt und entsprechend die Klassen erstellen lassen.
Siehe auch den weatherapi link oben wo man die Json File direkt abrufen kann um die es hier geht.

Dennoch wird bei strings überhaupt kein Wert zurückgegeben und bei Zahlen (float, int, double usw) eine 0
Wie bereits geschrieben, andere APIS funktionieren und geben mir korrekte Werte wieder daher glaub ich inzwischen, dass das an der Seite selbst liegt

2.078 Beiträge seit 2012
vor einem Jahr

Du deserialisierst in ein Objekt, das genau eine Property hat: localtime
Hat das JSON die Property "localtime"? Ich sehe da nur "location:localtime", großer Unterschied 😉

Also ja, dannoe hat Recht, Du brauchst ein Root-Objekt, was dann die location-Property enthält.
Dann musst Du auch kein tolles Visual Studio Feature nutzen, Du hättest einfach seinen Code kopieren können.

PS:
Ich weiß nicht, woher genau man den Key bekommt, aber es ist vermutlich immer eine schlechte Idee, sowas öffentlich zu machen 😉

V
VisualCsharpNoob Themenstarter:in
5 Beiträge seit 2022
vor einem Jahr

Du deserialisierst in ein Objekt, das genau eine Property hat: localtime
Hat das JSON die Property "localtime"? Ich sehe da nur "location:localtime", großer Unterschied 😉

Also ja, dannoe hat Recht, Du brauchst ein Root-Objekt, was dann die location-Property enthält.
Dann musst Du auch kein tolles Visual Studio Feature nutzen, Du hättest einfach seinen Code kopieren können.

PS:
Ich weiß nicht, woher genau man den Key bekommt, aber es ist vermutlich immer eine schlechte Idee, sowas öffentlich zu machen 😉

Hi, hinter der Api und dem Key steckt ein wegwerfaccount mit begrenzter Abrufmöglichkeit insofern egal ^^

Zu dem anderen Punkt: Ich hab da inzwischen gefühlt wie ein menschlicher Bruforce alle möglichen Kombinationen an Klassennamen und Objekten ausprobiert mit dem Ergebnis dass mir da einfach nie ein Wert zurückgegeben wird 😁 Andere Onlineapis funktionieren mit dem Code, das ist das was mich irgendwie stutzig macht. Ich weiß nicht ob es nun an mir, meinem Code oder an der Seite selbst liegt

V
VisualCsharpNoob Themenstarter:in
5 Beiträge seit 2022
vor einem Jahr

Ok. Liegt also doch nicht an der Seite sondern der Matrixfehler vor dem Bildschirm wie zu 99%. Bin auf die Lösung gekommen dank eurem Wink mit dem Zaunpfahl mit dem Rootobject. Vielen Dank dafür.

Ich hab zwar eine Rootobject Klasse mit Location und Current allerdings diese nicht zusätzlich deserialisiert


Rootobject Root = JsonConvert.DeserializeObject<Rootobject>(jsonInhalt);

Jetzt klappts auch mit dem Abrufen der Daten


Console.WriteLine(Root.location.name);
Console.WriteLine(Root.current.temp_c);

Warum es auf den anderen Seiten funktionierte lag schlicht und ergreifend daran, dass da keine Rootobject Klasse in der Hierarchie oben nötig waren